/******************************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Ltd.                       */
/*                                                                            */
/*  NAME      = db2_froca.c                                                   */
/*  NOTE      = TDS 请求解析                                                  */
/*  DATE      = 2015/03/19 by zhengxd                                         */
/******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#define DB2_UNICODEBIG     "UNICODEBIG"
#define DB2_UNICODE        "UNICODE"

#include "db2_exter.h"
#include "db2_base_type.h"

/*******************************************************************************
*  FUNC     :  创建参数名
*  ARGS     :  i_index (参数index)
*  RTN      :
*  NOTE     :
*******************************************************************************/
char* __db2_param_name(int i_index)
{
    /* 21 = strlen(PARAMETER) + 11 + 1 */
    char *p_param_name = NULL;

    p_param_name = (char *)frmalloc(21);
    if (p_param_name == NULL)
    {
        return NULL;
    }
    snprintf(p_param_name, 21, "%s%d", "PARAMETER", i_index);
    return p_param_name;
}

/*******************************************************************************
*  FUNC     :  取得1byte整形
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  p_st_frdata(数据)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_1byte_int(Frbyte_Packet *p_st_data
                 , int i_whole_flg
                 , unsigned int *p_ui_len
                 , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    uint8_t u8_int = 0;
    int8_t i8_int = 0;
    char *p_value = NULL;

    /* 格式不正 */
    if (*p_ui_len < 1)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (bytebuff_remaining(p_st_data) < 1)
    {
        goto unknow;
    }
    /* 取值 */
    i_ret = bytebuff_get_char(p_st_data, &u8_int);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 1字节整形最大-128~127 */
    p_value = (char *)frmalloc(5);
    if (p_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i8_int = (int8_t)u8_int;
    snprintf(p_value, 5, "%d", i8_int);
    p_st_frdata->p_field_value = p_value;
    *p_ui_len -= 1;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  取得2byte整形
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  i_typdef(数据类型)
*           :  p_st_frdata(数据)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_2byte_int(Frbyte_Packet *p_st_data
                 , int i_whole_flg
                 , int i_typdef
                 , unsigned int *p_ui_len
                 , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    uint16_t u16_int = 0;
    int16_t i16_int = 0;
    char *p_value = NULL;

    /* 格式不正 */
    if (*p_ui_len < 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (bytebuff_remaining(p_st_data) < 2)
    {
        goto unknow;
    }

    /* 取值 */
    switch (i_typdef)
    {
        /* QTDSQLX86/QTDSQLVAX字节序小头 */
        case DRDA_TYPDEF_QTDSQLX86:
        case DRDA_TYPDEF_QTDSQLVAX:
            i_ret = bytebuff_get_short(p_st_data, 2, &u16_int, BYTE_LITTLE_ENDIAN);
            break;

        /* QTDSQL370/QTDSQL400/QTDSQLASC字节序大头 */
        default:
            i_ret = bytebuff_get_short(p_st_data, 2, &u16_int, BYTE_BIG_ENDIAN);
            break;
    }
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i16_int = (int16_t)u16_int;

    /* 1字节整形最大-32768~32767 */
    p_value = (char *)frmalloc(7);
    if (p_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    snprintf(p_value, 7, "%d", i16_int);
    p_st_frdata->p_field_value = p_value;
    *p_ui_len -= 2;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  取得4byte整形
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  i_typdef(数据类型)
*           :  p_st_frdata(数据)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_4byte_int(Frbyte_Packet *p_st_data
                 , int i_whole_flg
                 , int i_typdef
                 , unsigned int *p_ui_len
                 , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    uint32_t u32_int = 0;
    int32_t i32_int = 0;
    char *p_value = NULL;

    /* 格式不正 */
    if (*p_ui_len < 4)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (bytebuff_remaining(p_st_data) < 4)
    {
        goto unknow;
    }

    /* 取值 */
    switch (i_typdef)
    {
        /* QTDSQLX86/QTDSQLVAX字节序小头 */
        case DRDA_TYPDEF_QTDSQLX86:
        case DRDA_TYPDEF_QTDSQLVAX:
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_int, BYTE_LITTLE_ENDIAN);
            break;

        /* QTDSQL370/QTDSQL400/QTDSQLASC字节序大头 */
        default:
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_int, BYTE_BIG_ENDIAN);
            break;
    }
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i32_int = (int32_t)u32_int;

    /* 1字节整形最大-2147483648~2147483647 */
    p_value = (char *)frmalloc(12);
    if (p_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    snprintf(p_value, 12, "%d", i32_int);
    p_st_frdata->p_field_value = p_value;
    *p_ui_len -= 4;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  取得8byte整形
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  i_typdef(数据类型)
*           :  p_st_frdata(数据)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_8byte_long(Frbyte_Packet *p_st_data
                  , int i_whole_flg
                  , int i_typdef
                  , unsigned int *p_ui_len
                  , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    uint64_t u64_int = 0;
    int64_t i64_int = 0;
    char *p_value = NULL;

    /* 格式不正 */
    if (*p_ui_len < 8)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (bytebuff_remaining(p_st_data) < 8)
    {
        goto unknow;
    }

    /* 取值 */
    switch (i_typdef)
    {
        /* QTDSQLX86/QTDSQLVAX字节序小头 */
        case DRDA_TYPDEF_QTDSQLX86:
        case DRDA_TYPDEF_QTDSQLVAX:
            i_ret = bytebuff_get_long(p_st_data, 8, &u64_int, BYTE_LITTLE_ENDIAN);
            break;

        /* QTDSQL370/QTDSQL400/QTDSQLASC字节序大头 */
        default:
            i_ret = bytebuff_get_long(p_st_data, 8, &u64_int, BYTE_BIG_ENDIAN);
            break;
    }
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i64_int = (int64_t)u64_int;

    /* 1字节整形最大-9223372036854775808~9223372036854775807 */
    p_value = (char *)frmalloc(21);
    if (p_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

# if __WORDSIZE == 64
    snprintf(p_value, 21, "%ld", i64_int);
# else
__extension__
    snprintf(p_value, 21, "%lld", i64_int);
# endif
    p_st_frdata->p_field_value = p_value;
    *p_ui_len -= 8;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  取得4byte浮点型
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  i_typdef(type define)
*           :  p_st_frdata(数据)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_4byte_float(Frbyte_Packet *p_st_data
                   , int i_whole_flg
                   , int i_typdef
                   , unsigned int *p_ui_len
                   , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    int i_flt_value = 0;
    char *p_value = NULL;
    uint32_t u32_flt_value = 0;
    union int32_float_bits u_32bits;
    float f_float_value = 0.0;

    /* 格式不正 */
    if (*p_ui_len < 4)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (bytebuff_remaining(p_st_data) < 4)
    {
        goto unknow;
    }

    /* 取得4位数据 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_flt_value, BYTE_LITTLE_ENDIAN);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 根据type define取值 */
    switch (i_typdef)
    {
        /* QTDSQLX86/QTDSQLVAX字节序小头 */
        case DRDA_TYPDEF_QTDSQLX86:
        case DRDA_TYPDEF_QTDSQLVAX:
        case DRDA_TYPDEF_QTDSQL370:
        case DRDA_TYPDEF_QTDSQL400:
        case DRDA_TYPDEF_QTDSQLASC:
            i_flt_value = (int)u32_flt_value;
            u_32bits.int_bits = i_flt_value;
            f_float_value = u_32bits.float_bits;
            p_value = (char *)frmalloc(32);
            if (p_value == NULL)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            snprintf(p_value, 32, "%f", f_float_value);
            break;
    }

    p_st_frdata->p_field_value = p_value;
    *p_ui_len -= 4;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  取得8byte浮点型
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  i_typdef(type define)
*           :  p_st_frdata(数据)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_8byte_float(Frbyte_Packet *p_st_data
                   , int i_whole_flg
                   , int i_typdef
                   , unsigned int *p_ui_len
                   , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    long long ll_flt_value = 0;
    char *p_value = NULL;
    uint64_t u64_flt_value = 0;
    union int64_double_bits u_64bits;
    double d_double_value = 0.0;

    /* 格式不正 */
    if (*p_ui_len < 8)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (bytebuff_remaining(p_st_data) < 8)
    {
        goto unknow;
    }

    /* 取得8位数据 */
    i_ret = bytebuff_get_long(p_st_data, 8, &u64_flt_value, BYTE_LITTLE_ENDIAN);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 根据type define取值 */
    switch (i_typdef)
    {
        /* QTDSQLX86/QTDSQLVAX字节序小头 */
        case DRDA_TYPDEF_QTDSQLX86:
        case DRDA_TYPDEF_QTDSQLVAX:
        case DRDA_TYPDEF_QTDSQL370:
        case DRDA_TYPDEF_QTDSQL400:
        case DRDA_TYPDEF_QTDSQLASC:
            ll_flt_value = (long long)u64_flt_value;
            u_64bits.int_bits = ll_flt_value;
            d_double_value = u_64bits.double_bits;
            p_value = (char *)frmalloc(32);
            if (p_value == NULL)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            snprintf(p_value, 32, "%lf", d_double_value);
            break;
    }

    p_st_frdata->p_field_value = p_value;
    *p_ui_len -= 8;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  取得16byte浮点型
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  i_typdef(type define)
*           :  p_st_frdata(数据)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_16byte_float(Frbyte_Packet *p_st_data
                    , int i_whole_flg
                    , int i_typdef
                    , unsigned int *p_ui_len
                    , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    char *p_value = NULL;
    char arr_value[16] = {0};

    /* 格式不正 */
    if (*p_ui_len < 16)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (bytebuff_remaining(p_st_data) < 16)
    {
        goto unknow;
    }

    /* 取得8位数据 */
    i_ret = bytebuff_get_bytes(p_st_data, arr_value, 16);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 根据type define取值 */
    switch (i_typdef)
    {
        /* QTDSQLX86/QTDSQLVAX字节序小头 */
        case DRDA_TYPDEF_QTDSQLX86:
        case DRDA_TYPDEF_QTDSQLVAX:
        case DRDA_TYPDEF_QTDSQL370:
        case DRDA_TYPDEF_QTDSQL400:
        case DRDA_TYPDEF_QTDSQLASC:
            //todo 现在未解析 arr_value转换成float
            break;
    }

    p_st_frdata->p_field_value = p_value;
    *p_ui_len -= 16;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  取得Fixed Decimal
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  ui_scale(scale)
*           :  ui_precision(precision)
*           :  p_st_frdata(数据)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_fixed_dec(Frbyte_Packet *p_st_data
                 , int i_whole_flg
                 , unsigned int ui_scale
                 , unsigned int ui_precision
                 , unsigned int *p_ui_len
                 , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    char *p_value = NULL;
    char *p_tmp = NULL;
    unsigned int ui_loop = 0;
    int i_index = 0;
    int i_get_flg = DB2_FALSE;
    unsigned int ui_len = 0;
    unsigned int ui_value_len = 0;
    unsigned int ui_acl_len = 0;

    /* 根据scale确定要取得长 */
    ui_len = ui_scale/2 + 1;

    /* 格式不正 */
    if (*p_ui_len < ui_len)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (ui_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        goto unknow;
    }

    p_tmp = (char *)frmalloc(ui_len);
    if (p_tmp == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 取得数据 */
    i_ret = bytebuff_get_bytes(p_st_data, p_tmp, ui_len);
    if (i_ret != FR_SUCC)
    {
        frfree(p_tmp);
        return APM_L7_ANALYZE_FAIL;
    }

    /* 申请足够内存 */
    ui_value_len = (ui_scale + ui_precision) * 2 + 10;
    p_value = (char *)frmalloc(ui_value_len);
    if (p_value == NULL)
    {
        frfree(p_tmp);
        return APM_L7_ANALYZE_FAIL;
    }
    memset(p_value, 0x0, ui_value_len);

    /* 确定正负最后一个字节是0xXD为负数 */
    if ((p_tmp[ui_len - 1] & 0x0F) == 0x0D)
    {
        p_value[i_index++] = '-';
    }

    /* 取值 */
    for (ui_loop = 0; ui_loop < ui_len; ui_loop++)
    {
        if (p_tmp[ui_loop])
        {
            if (i_get_flg == DB2_FALSE && p_tmp[ui_loop] <= 9)
            {
                snprintf(p_value + i_index, ui_value_len - i_index, "%d", p_tmp[ui_loop]);
                i_index++;
            }
            else
            {
                snprintf(p_value + i_index, ui_value_len - i_index, "%02X", p_tmp[ui_loop]);
                i_index += 2;
            }
            i_get_flg = DB2_TRUE;
        }
        else if (i_get_flg == DB2_TRUE)
        {
            snprintf(p_value + i_index, ui_value_len - i_index, "00");
            i_index += 2;
        }
    }
    frfree(p_tmp);
    /* 校区最后一个符号位 */
    ui_acl_len = strlen(p_value);
    if (ui_acl_len > 2)
    {
        p_value[ui_acl_len - 1] = '\0';
        ui_acl_len--;
    }
    /* 值为0 */
    else
    {
        *p_value = '0';
        p_st_frdata->p_field_value = p_value;
        *p_ui_len -= ui_len;
        return APM_L7_ANALYZE_SUCC;
    }

    /* 根据precision设置小数点 */
    if (ui_precision)
    {
        if (*p_value == '-')
        {
            /* 需要前补零 */
            if (ui_precision >= ui_acl_len - 1)
            {
                memmove(p_value + ui_precision - ui_acl_len + 4
                       , p_value + 1, ui_acl_len + 1);
                memset(p_value + 1, '0', ui_precision - ui_acl_len + 3);
                p_value[2] = '.';
            }
            else
            {
                memmove(p_value + ui_acl_len - ui_precision + 1
                       , p_value + ui_acl_len - ui_precision
                       , ui_precision + 1);
               p_value[ui_acl_len - ui_precision] = '.';
            }
        }
        else
        {
            /* 需要前补零 */
            if (ui_precision >= ui_acl_len)
            {
                memmove(p_value + ui_precision - ui_acl_len + 2
                       , p_value, ui_acl_len + 1);
                memset(p_value, '0', ui_precision - ui_acl_len + 2);
                p_value[1] = '.';
            }
            else
            {
                memmove(p_value + ui_acl_len - ui_precision + 1
                       , p_value + ui_acl_len - ui_precision
                       , ui_precision + 1);
               p_value[ui_acl_len - ui_precision] = '.';
            }
        }
    }

    p_st_frdata->p_field_value = p_value;
    *p_ui_len -= ui_len;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  跳过指定bytes
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  ui_skip_len(要跳过的数据长度)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_skip_bytes(Frbyte_Packet *p_st_data
                  , int i_whole_flg
                  , unsigned int *p_ui_len
                  , unsigned int ui_skip_len)
{
    /* 格式不正 */
    if (*p_ui_len < ui_skip_len)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (ui_skip_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        goto unknow;
    }

    bytebuff_skip(p_st_data, ui_skip_len);
    *p_ui_len -= ui_skip_len;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  跳过可变bytes
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_skip_varbytes(Frbyte_Packet *p_st_data
                     , int i_whole_flg
                     , unsigned int *p_ui_len
                     , int i_double_single)
{
    int i_ret = FR_SUCC;
    uint16_t u16_len = 0;
    unsigned int ui_len = *p_ui_len;
    unsigned int ui_value_len = 0;

    /* 两个bytes位 */
    /* 格式不正 */
    if (*p_ui_len < 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (bytebuff_remaining(p_st_data) < 2)
    {
        goto unknow;
    }

    /* 取得长度 */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_len -= 2;
    ui_value_len = u16_len * i_double_single;

    /* 格式不正 */
    if (ui_len < ui_value_len)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (ui_value_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        goto unknow;
    }

    ui_len -= ui_value_len;
    bytebuff_skip(p_st_data, ui_value_len);
    *p_ui_len = ui_len;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  取得Zoned Decimal
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  ui_scale(scale)
*           :  ui_precision(precision)
*           :  p_st_frdata(数据)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_zoned_dec(Frbyte_Packet *p_st_data
                 , int i_whole_flg
                 , unsigned int ui_scale
                 , unsigned int ui_precision
                 , unsigned int *p_ui_len
                 , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    char *p_value = NULL;
    char *p_tmp = NULL;
    unsigned int ui_loop = 0;
    int i_index = 0;
    int i_get_flg = DB2_FALSE;
    unsigned int ui_value_len = 0;
    unsigned int ui_acl_len = 0;

    /* 格式不正 */
    if (*p_ui_len < ui_scale)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (ui_scale > (unsigned int)bytebuff_remaining(p_st_data))
    {
        goto unknow;
    }

    p_tmp = (char *)frmalloc(ui_scale);
    if (p_tmp == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 取得数据 */
    i_ret = bytebuff_get_bytes(p_st_data, p_tmp, ui_scale);
    if (i_ret != FR_SUCC)
    {
        frfree(p_tmp);
        return APM_L7_ANALYZE_FAIL;
    }

    /* 申请足够内存 */
    ui_value_len = (ui_scale + ui_precision) * 2 + 10;
    p_value = (char *)frmalloc(ui_value_len);
    if (p_value == NULL)
    {
        frfree(p_tmp);
        return APM_L7_ANALYZE_FAIL;
    }
    memset(p_value, 0x0, ui_value_len);
    /* 确定正负最后一个字节是0xXD为负数 */
    if ((p_tmp[ui_scale - 1] & 0xF0) == 0xD0)
    {
        p_value[i_index++] = '-';
    }

    /* 取值 */
    for (ui_loop = 0; ui_loop < ui_scale; ui_loop++)
    {
        if (p_tmp[ui_loop] & 0x0F)
        {
            snprintf(p_value + i_index, ui_value_len - i_index, "%X", (p_tmp[ui_loop] & 0x0F));
            i_get_flg = DB2_TRUE;
            i_index++;
        }
        else if (i_get_flg == DB2_TRUE)
        {
            snprintf(p_value + i_index, ui_value_len - i_index, "0");
            i_index++;
        }
    }
    frfree(p_tmp);

    ui_acl_len = strlen(p_value);
    /* 值为0 */
    if (ui_acl_len == 0)
    {
        *p_value = '\0';
        p_st_frdata->p_field_value = p_value;
        *p_ui_len -= ui_scale;
        return APM_L7_ANALYZE_SUCC;
    }

    /* 根据precision设置小数点 */
    if (ui_precision)
    {
        if (*p_value == '-')
        {
            /* 需要前补零 */
            if (ui_precision >= ui_acl_len - 1)
            {
                memmove(p_value + ui_precision - ui_acl_len + 4
                       , p_value + 1, ui_acl_len + 1);
                memset(p_value + 1, '0', ui_precision - ui_acl_len + 3);
                p_value[2] = '.';
            }
            else
            {
                memmove(p_value + ui_acl_len - ui_precision + 1
                       , p_value + ui_acl_len - ui_precision
                       , ui_precision + 1);
               p_value[ui_acl_len - ui_precision] = '.';
            }
        }
        else
        {
            /* 需要前补零 */
            if (ui_precision >= ui_acl_len)
            {
                memmove(p_value + ui_precision - ui_acl_len + 2
                       , p_value, ui_acl_len + 1);
                memset(p_value, '0', ui_precision - ui_acl_len + 2);
                p_value[1] = '.';
            }
            else
            {
                memmove(p_value + ui_acl_len - ui_precision + 1
                       , p_value + ui_acl_len - ui_precision
                       , ui_precision + 1);
               p_value[ui_acl_len - ui_precision] = '.';
            }
        }
    }
    p_st_frdata->p_field_value = p_value;
    *p_ui_len -= ui_scale;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  跳过大数据
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  ui_scale(scale)
*           :  ui_precision(precision)
*           :  p_st_frdata(数据)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_skip_lob(Frbyte_Packet *p_st_data
                , int i_whole_flg
                , unsigned int *p_ui_len
                , int i_double_single)
{
    int i_ret = FR_SUCC;
    uint8_t u8_extern_flg = 0;
    uint64_t u64_len = 0;
    unsigned int ui_len = *p_ui_len;

    /* 根据数据包得知:大数据开头由1位index位+8位长度 */
    /* 格式不正 */
    if (ui_len < 1 + 8)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 数据不足 */
    if (bytebuff_remaining(p_st_data) < 1 + 8)
    {
        goto unknow;
    }

    /* 取得extern标识 */
    i_ret = bytebuff_get_char(p_st_data, &u8_extern_flg);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 取得长度位 */
    i_ret = bytebuff_get_long(p_st_data, 8, &u64_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    u64_len *= i_double_single;
    ui_len -= 9;

    /* extern标识为2时数据再extern中 */
    if (u8_extern_flg == 1)
    {
        /* 长度不正 */
        if (u64_len > ui_len)
        {
            return APM_L7_ANALYZE_FAIL;
        }

        /* 数据不足 */
        if (u64_len > (unsigned int)bytebuff_remaining(p_st_data))
        {
            bytebuff_set_skip(p_st_data, ((unsigned int)u64_len) - bytebuff_remaining(p_st_data));
            goto unknow;
        }

        /* 跳过数据块 */
        bytebuff_skip(p_st_data, (unsigned int)u64_len);
        ui_len -= (unsigned int)u64_len;
    }

    *p_ui_len = ui_len;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  取得固定长度的双字节字符
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  i_typdef(数据类型)
*           :  ui_len(数据长度)
*           :  ui_fixed_len(固定长度)
*           :  p_st_frdata(参数)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_get_fd_chars(Frbyte_Packet *p_st_data
                    , int i_whole_flg
                    , int i_typdef
                    , unsigned int *p_ui_len
                    , unsigned int ui_fixed_len
                    , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    unsigned int ui_value_len = 0;
    unsigned int ui_binary_len = 0;
    char *p_value = NULL;
    char *p_binary = NULL;

    ui_binary_len = ui_fixed_len * 2;
    /* 格式不正 */
    if (*p_ui_len < ui_binary_len)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (ui_binary_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        goto unknow;
    }

    /* 取得源数据 */
    p_binary = (char *)frmalloc(ui_binary_len);
    if (p_binary == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i_ret = bytebuff_get_bytes(p_st_data, p_binary, ui_binary_len);
    if (i_ret != FR_SUCC)
    {
        frfree(p_binary);
        return APM_L7_ANALYZE_FAIL;
    }

    /* unicode转utf-8 */
    switch (i_typdef)
    {
        /* QTDSQLX86/QTDSQLVAX字节序小头 */
        case DRDA_TYPDEF_QTDSQLX86:
        case DRDA_TYPDEF_QTDSQLVAX:
            i_ret = iconv_to_utf8(p_binary, ui_binary_len, DB2_UNICODE, &p_value, &ui_value_len);
            break;

        /* QTDSQL370/QTDSQL400/QTDSQLASC字节序大头 */
        default:
            i_ret = iconv_to_utf8(p_binary, ui_binary_len, DB2_UNICODEBIG, &p_value, &ui_value_len);
            break;
    }
    frfree(p_binary);
    if (i_ret == 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    *p_ui_len -= ui_binary_len;
    p_st_frdata->p_field_value = p_value;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  取得固定长度的单字节字符
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  ui_fixed_len(固定长度)
*           :  p_st_frdata(参数)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_get_fs_chars(Frbyte_Packet *p_st_data
                    , int i_whole_flg
                    , unsigned int *p_ui_len
                    , unsigned int ui_fixed_len
                    , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    unsigned int ui_value_len = 0;
    char *p_value = NULL;

    ui_value_len = ui_fixed_len;
    /* 格式不正 */
    if (*p_ui_len < ui_value_len)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (ui_value_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        goto unknow;
    }

    /* 取得源数据 */
    p_value = (char *)frmalloc(ui_value_len + 1);
    if (p_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i_ret = bytebuff_get_bytes(p_st_data, p_value, ui_value_len);
    if (i_ret != FR_SUCC)
    {
        frfree(p_value);
        return APM_L7_ANALYZE_FAIL;
    }
    p_value[ui_value_len] = '\0';

    *p_ui_len -= ui_value_len;
    p_st_frdata->p_field_value = p_value;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  取得不固定长度的双字节字符
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  i_typdef(数据类型)
*           :  p_ui_len(数据长度)
*           :  p_st_frdata(参数)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_get_vd_chars(Frbyte_Packet *p_st_data
                    , int i_whole_flg
                    , int i_typdef
                    , unsigned int *p_ui_len
                    , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    uint16_t u16_len = 0;
    unsigned int ui_len = *p_ui_len;
    unsigned int ui_value_len = 0;
    unsigned int ui_binary_len = 0;
    char *p_value = NULL;
    char *p_binary = NULL;

    /* 两个bytes位 */
    /* 格式不正 */
    if (ui_len < 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (bytebuff_remaining(p_st_data) < 2)
    {
        goto unknow;
    }
    /* 取得长度位 */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_len -= 2;

    ui_binary_len = u16_len * 2;
    /* 长度不正 */
    if (ui_len < ui_binary_len)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (ui_binary_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        goto unknow;
    }

    /* 取得源数据 */
    p_binary = (char *)frmalloc(ui_binary_len);
    if (p_binary == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i_ret = bytebuff_get_bytes(p_st_data, p_binary, ui_binary_len);
    if (i_ret != FR_SUCC)
    {
        frfree(p_binary);
        return APM_L7_ANALYZE_FAIL;
    }

    /* unicode转utf-8 */
    switch (i_typdef)
    {
        /* QTDSQLX86/QTDSQLVAX字节序小头 */
        case DRDA_TYPDEF_QTDSQLX86:
        case DRDA_TYPDEF_QTDSQLVAX:
            i_ret = iconv_to_utf8(p_binary, ui_binary_len, DB2_UNICODE, &p_value, &ui_value_len);
            break;

        /* QTDSQL370/QTDSQL400/QTDSQLASC字节序大头 */
        default:
            i_ret = iconv_to_utf8(p_binary, ui_binary_len, DB2_UNICODEBIG, &p_value, &ui_value_len);
            break;
    }
    frfree(p_binary);
    if (i_ret == 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    ui_len -= ui_binary_len;
    p_st_frdata->p_field_value = p_value;
    *p_ui_len = ui_len;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  取得不固定长度的单字节字符
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  p_st_frdata(参数)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_frdata必须不为NULL
*******************************************************************************/
int db2_get_vs_chars(Frbyte_Packet *p_st_data
                    , int i_whole_flg
                    , unsigned int *p_ui_len
                    , Frdata_field *p_st_frdata)
{
    int i_ret = FR_SUCC;
    uint16_t u16_len = 0;
    unsigned int ui_len = *p_ui_len;
    unsigned int ui_value_len = 0;
    char *p_value = NULL;

    /* 两个bytes位 */
    /* 格式不正 */
    if (ui_len < 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (bytebuff_remaining(p_st_data) < 2)
    {
        goto unknow;
    }
    /* 取得长度位 */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_len -= 2;

    /* 长度不正 */
    if (ui_len < u16_len)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* 数据不足 */
    if (bytebuff_remaining(p_st_data) < u16_len)
    {
        goto unknow;
    }

    /* 取得源数据 */
    ui_value_len = u16_len;
    p_value = (char *)frmalloc(ui_value_len + 1);
    if (p_value == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i_ret = bytebuff_get_bytes(p_st_data, p_value, ui_value_len);
    if (i_ret != FR_SUCC)
    {
        frfree(p_value);
        return APM_L7_ANALYZE_FAIL;
    }
    p_value[ui_value_len] = '\0';

    ui_len -= ui_value_len;
    p_st_frdata->p_field_value = p_value;
    *p_ui_len = ui_len;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  跳过NVCM 和 NVCS
*  ARGS     :  p_st_data (实际数据)
*           :  p_ui_left_ddm_len(遗留长度)
*           :  i_whole_flg(packet是否完整)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  遗留长度必须大于实际数据长度
*******************************************************************************/
int db2_parse_nvcm_nvcs(Frbyte_Packet *p_st_data
                        , unsigned int *p_ui_left_ddm_len
                        , int i_whole_flg)
{
    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_flg = 0;
    uint16_t u16_len = 0;
    unsigned int ui_left_ddm_len = *p_ui_left_ddm_len;

    /* 格式判断 */
    if (ui_left_ddm_len < 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 取得NVCM NULLABLE FLAG */
    i_ret = bytebuff_get_char(p_st_data, &u8_flg);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_left_ddm_len--;

    /* NVCM是NULL */
    if (u8_flg == 0xFF)
    {
        /* 取得NVCS NULLABLE FLAG */
        i_ret = bytebuff_get_char(p_st_data, &u8_flg);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        ui_left_ddm_len--;
        /* NVCS不是NULL */
        if (u8_flg != 0xFF)
        {
            if (ui_left_ddm_len < 2)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
            if (i_ret != FR_SUCC || ui_left_ddm_len < (unsigned int)(u16_len + 2))
            {
                return APM_L7_ANALYZE_FAIL;
            }
            bytebuff_skip(p_st_data, u16_len);
            ui_left_ddm_len -= u16_len + 2;
        }
    }
    else
    {
        if (ui_left_ddm_len < 2)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
        if (i_ret != FR_SUCC || ui_left_ddm_len < (unsigned int)(u16_len + 2 + 1))
        {
            return APM_L7_ANALYZE_FAIL;
        }
        bytebuff_skip(p_st_data, u16_len);
        ui_left_ddm_len -= u16_len + 2 + 1;
        /* 取得NVCS NULLABLE FLAG */
        i_ret = bytebuff_get_char(p_st_data, &u8_flg);
        if (i_ret != FR_SUCC || u8_flg != 0xFF)
        {
            return APM_L7_ANALYZE_FAIL;
        }
    }

    *p_ui_left_ddm_len = ui_left_ddm_len;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析SQLDCXGRP
*  ARGS     :  p_st_data (实际数据)
*           :  p_ui_left_ddm_len(遗留长度)
*           :  i_whole_flg(packet是否完整)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  遗留长度必须大于实际数据长度
*******************************************************************************/
int db2_parse_sqldcxgrp(Frbyte_Packet *p_st_data
                        , unsigned int *p_ui_left_ddm_len
                        , int i_whole_flg)

{
    /* SQLDCXGRP格式
    *  SQLDCXGRP = SQLDCXRDB(VCS)
    *              SQLDCXSCH_m(NVCM)
    *              SQLDCXSCH_s(NVCS)
    *              SQLDCXNAM_m(NVCM)
    *              SQLDCXNAM_s(NVCS)
    *              SQLDCXTBLN_m(NVCM)
    *              SQLDCXTBLN_s(NVCS)
    *              SQLDCXCRDB(VCS)
    *              SQLDCXCSCH_m(NVCM)
    *              SQLDCXCSCH_s(NVCS)
    *              SQLDCXCNAM_m(NVCM)
    *              SQLDCXCNAM_s(NVCS)
    *              SQLDCXRRDB(VCS)
    *              SQLDCXRSCH_m(NVCM)
    *              SQLDCXRSCH_s(NVCS)
    *              SQLDCXRNAM_m(NVCM)
    *              SQLDCXRNAM_s(NVCS)
    *              SQLDCXTRDB(VCS)
    *              SQLDCXTSCH_m(NVCM)
    *              SQLDCXTSCH_s(NVCS)
    *              SQLDCXTNAM_m(NVCM)
    *              SQLDCXTNAM_s(NVCS)
    *              SQLDCXMOD_m(NVCM)
    *              SQLDCXMOD_s(NVCS)
    *              SQLDCXRMOD_m(NVCM)
    *              SQLDCXRMOD_s(NVCS)
    */
    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_flg = 0;
    uint16_t u16_len = 0;
    unsigned int ui_left_ddm_len = *p_ui_left_ddm_len;

    /* 根据协议SQLDCXGRP必须大于等于1 */
    if (ui_left_ddm_len == 0)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* SQLDCXGRP FLAG */
    i_ret = bytebuff_get_char(p_st_data, &u8_flg);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_left_ddm_len--;

    /* SQLDCXGRP结束 */
    if (u8_flg == 0xFF)
    {
        *p_ui_left_ddm_len = ui_left_ddm_len;
        return APM_L7_ANALYZE_SUCC;
    }
    else if (u8_flg != 0x00)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* SQLDCXRDB(VCS) */
    if (ui_left_ddm_len < 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || ui_left_ddm_len < (unsigned int)(u16_len + 2))
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, u16_len);
    ui_left_ddm_len -= u16_len + 2;

    /* SQLDCXSCH_m(NVCM ) + SQLDCXSCH_s(NVCS ) */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCXNAM_m(NVCM) + SQLDCXNAM_s(NVCS) */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCXTBLN_m(NVCM) + SQLDCXTBLN_s(NVCS) */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCXCRDB(VCS) */
    if (ui_left_ddm_len < 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || ui_left_ddm_len < (unsigned int)(u16_len + 2))
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, u16_len);
    ui_left_ddm_len -= u16_len + 2;
    /* SQLDCXCSCH_m(NVCM) + SQLDCXCSCH_s(NVCS) */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCXCNAM_m(NVCM) + SQLDCXCNAM_s(NVCS) */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCXRRDB(VCS) */
    if (ui_left_ddm_len < 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || ui_left_ddm_len < (unsigned int)(u16_len + 2))
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, u16_len);
    ui_left_ddm_len -= u16_len + 2;
    /* SQLDCXRSCH_m(NVCM) + SQLDCXRSCH_s(NVCS) */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCXRNAM_m(NVCM) + SQLDCXRNAM_s(NVCS) */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCXTRDB(VCS) */
    if (ui_left_ddm_len < 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || ui_left_ddm_len < (unsigned)(u16_len + 2))
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, u16_len);
    ui_left_ddm_len -= u16_len + 2;
    /* SQLDCXTSCH_m(NVCM) + SQLDCXTSCH_s(NVCS) */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCXTNAM_m(NVCM) + SQLDCXTNAM_s(NVCS) */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCXMOD_m(NVCM) + SQLDCXMOD_s(NVCS) */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCXRMOD_m(NVCM) + SQLDCXRMOD_s(NVCS) */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }

    *p_ui_left_ddm_len = ui_left_ddm_len;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析SQLCNROW
*  ARGS     :  p_st_data (实际数据)
*           :  p_ui_left_ddm_len(遗留长度)
*           :  i_whole_flg(packet是否完整)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  遗留长度必须大于实际数据长度
*******************************************************************************/
int db2_parse_sqlcnrow(Frbyte_Packet *p_st_data
                       , unsigned int *p_ui_left_ddm_len
                       , int i_whole_flg)
{
    /* SQLCNROW格式
    *  SQLCNROW = SQLCNSTATE(I4)
    *             SQLCNSTATUS(I4)
    *             SQLCNATYPE(1-byte FCS)
    *             SQLCNETYPE(1-byteFCS)
    *             SQLCNPRDID(8-byteFCS)
    *             SQLCNRDB(VCS)
    *             SQLCNCLASS(VCS)
    *             SQLCNAUTHID(VCS)
    */
    int i_ret = APM_L7_ANALYZE_SUCC;
    uint16_t u16_len = 0;
    unsigned int ui_left_ddm_len = *p_ui_left_ddm_len;

    /* 18是SQLCNSTATE + SQLCNSTATUS + SQLCNATYPE + SQLCNETYPE + SQLCNPRDID */
    if (ui_left_ddm_len < 18 + 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, 18);
    ui_left_ddm_len -= 18 + 2;

    /* 跳过SQLCNRDB */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || ui_left_ddm_len < (unsigned int)(u16_len + 2))
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, u16_len);
    ui_left_ddm_len -= u16_len + 2;

    /* 跳过SQLCNCLASS */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || ui_left_ddm_len < (unsigned int)(u16_len + 2))
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, u16_len);
    ui_left_ddm_len -= u16_len + 2;

    /* 跳过SQLCNAUTHID */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || ui_left_ddm_len < u16_len)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, u16_len);
    ui_left_ddm_len -= u16_len;

    *p_ui_left_ddm_len = ui_left_ddm_len;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析SQLDCROW
*  ARGS     :  p_st_data (实际数据)
*           :  p_ui_left_ddm_len(遗留长度)
*           :  i_whole_flg(packet是否完整)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  遗留长度必须大于实际数据长度
*******************************************************************************/
int db2_parse_sqldcrow(Frbyte_Packet *p_st_data
                       , unsigned int *p_ui_left_ddm_len
                       , int i_whole_flg)
{
    /* SQLDCROW格式
    *  SQLDCROW = SQLDCCODE(4-byte integer)
    *             SQLDCSTATE(5-byte character field)
    *             SQLDCREASON(4-byte integer)
    *             SQLDCLINEN(4-byte integer)
    *             SQLDCROWN(8-byte integer)
    *             SQLDCER01(4-byte integer)
    *             SQLDCER02(4-byte integer)
    *             SQLDCER03(4-byte integer)
    *             SQLDCER04(4-byte integer)
    *             SQLDCPART(4-byte integer)
    *             SQLDCPPOP(4-byte integer)
    *             SQLDCMSGID(10-byte character field)
    *             SQLDCMDE(8-byte character field)
    *             SQLDCPMOD(5-byte character field)
    *             SQLDCRDB(variable character field)
    *             SQLDCTOKS(参照SQLDCTOKS)
    *             SQLDCMSG_m(nullable variable character field)
    *             SQLDCMSG_s(nullable variable character field)
    *             SQLDCCOLN_m(nullable variable character field)
    *             SQLDCCOLN_s(nullable variable character field)
    *             SQLDCCURN_m(nullable variable character field)
    *             SQLDCCURN_s(nullable variable character field)
    *             SQLDCPNAM_m(nullable variable character field)
    *             SQLDCPNAM_s(nullable variable character field)
    *             SQLDCXGRP(参照SQLDCXGRP)
    */
    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_flg = 0;
    uint16_t u16_num = 0;
    uint16_t u16_len = 0;
    unsigned int ui_left_ddm_len = *p_ui_left_ddm_len;

    /* 74是SQLDCCODE到SQLDCPMOD的长度 + SQLDCRDB的长度位 */
    if (ui_left_ddm_len < 74)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, 72);
    ui_left_ddm_len -= 74;

    /* 跳过SQLDCRDB */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || ui_left_ddm_len < (unsigned int)(u16_len + 1))
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, u16_len);
    ui_left_ddm_len -= u16_len + 1;

    /* 跳过SQLDCTOKS */
    i_ret = bytebuff_get_char(p_st_data, &u8_flg);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    if (u8_flg != 0xFF)
    {
        /* 取得SQLNUMROW */
        if (ui_left_ddm_len < 2)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        i_ret = bytebuff_get_short(p_st_data, 2, &u16_num, BYTE_LITTLE_ENDIAN);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        ui_left_ddm_len -= 2;
        /* 解析SQLTOKROW */
        while (u16_num)
        {
            u16_num--;
            i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
            if (i_ret != APM_L7_ANALYZE_SUCC)
            {
                return i_ret;
            }
        }
    }

    /* SQLDCMSG_m + SQLDCMSG_s */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCCOLN_m + SQLDCCOLN_s */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCCURN_m + SQLDCCURN_s */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }
    /* SQLDCPNAM_m + SQLDCPNAM_s */
    i_ret = db2_parse_nvcm_nvcs(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }

    /* 解析SQLDCXGRP */
    i_ret = db2_parse_sqldcxgrp(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }

    *p_ui_left_ddm_len = ui_left_ddm_len;
    return APM_L7_ANALYZE_SUCC;
}


/*******************************************************************************
*  FUNC     :  解析SQLDIAGCN
*  ARGS     :  p_st_data (实际数据)
*           :  p_ui_left_ddm_len(遗留长度)
*           :  i_whole_flg(packet是否完整)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  遗留长度必须大于实际数据长度
*******************************************************************************/
int db2_parse_sqldiagcn(Frbyte_Packet *p_st_data
                       , unsigned int *p_ui_left_ddm_len
                       , int i_whole_flg)
{
    /* SQLDIAGCN格式
    *  SQLDIAGCN = SQLNUMROW
    *              SQLCNROW(参照SQLCNROW)
    */
    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_flg = 0;
    uint16_t u16_num = 0;
    unsigned int ui_left_ddm_len = *p_ui_left_ddm_len;

    /* 根据协议SQLDIAGCN必须大于等于1 */
    if (ui_left_ddm_len == 0)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* SQLDIAGCN FLAG */
    i_ret = bytebuff_get_char(p_st_data, &u8_flg);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_left_ddm_len--;

    /* SQLDIAGCN结束 */
    if (u8_flg == 0xFF)
    {
        *p_ui_left_ddm_len = ui_left_ddm_len;
        return APM_L7_ANALYZE_SUCC;
    }
    else if (u8_flg != 0x00)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 取得SQLNUMROW */
    if (ui_left_ddm_len < 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_num, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_left_ddm_len -= 2;

    /* 解析SQLCNROW */
    while (u16_num)
    {
        u16_num--;
        i_ret = db2_parse_sqlcnrow(p_st_data, &ui_left_ddm_len, i_whole_flg);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            return i_ret;
        }
    }

    *p_ui_left_ddm_len = ui_left_ddm_len;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析SQLDIAGCI
*  ARGS     :  p_st_data (实际数据)
*           :  p_ui_left_ddm_len(遗留长度)
*           :  i_whole_flg(packet是否完整)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  遗留长度必须大于实际数据长度
*******************************************************************************/
int db2_parse_sqldiagci(Frbyte_Packet *p_st_data
                       , unsigned int *p_ui_left_ddm_len
                       , int i_whole_flg)
{
    /* SQLDIAGCI格式
    *  SQLDIAGCI = SQLNUMROW
    *              SQLDCROW(参照SQLDCROW)
    */
    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_flg = 0;
    uint16_t u16_num = 0;
    unsigned int ui_left_ddm_len = *p_ui_left_ddm_len;

    /* 根据协议SQLDIAGCI必须大于等于1 */
    if (ui_left_ddm_len == 0)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* SQLDIAGCI FLAG */
    i_ret = bytebuff_get_char(p_st_data, &u8_flg);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_left_ddm_len--;

    /* SQLDIAGCI结束 */
    if (u8_flg == 0xFF)
    {
        *p_ui_left_ddm_len = ui_left_ddm_len;
        return APM_L7_ANALYZE_SUCC;
    }
    else if (u8_flg != 0x00)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 取得SQLNUMROW */
    if (ui_left_ddm_len < 2)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_num, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_left_ddm_len -= 2;

    /* 解析sqldcrow */
    while (u16_num)
    {
        u16_num--;
        i_ret = db2_parse_sqldcrow(p_st_data, &ui_left_ddm_len, i_whole_flg);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            return i_ret;
        }
    }

    *p_ui_left_ddm_len = ui_left_ddm_len;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析SQLDIAGSTT
*  ARGS     :  p_st_data (实际数据)
*           :  p_ui_left_ddm_len(遗留长度)
*           :  i_whole_flg(packet是否完整)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  遗留长度必须大于实际数据长度
*******************************************************************************/
int db2_parse_sqldiagstt(Frbyte_Packet *p_st_data
                        , unsigned int *p_ui_left_ddm_len
                        , int i_whole_flg)
{
    /* SQLDIAGSTT格式
    *  SQLDIAGSTT = SQLDSFCOD(4-byte integer)
    *               SQLDSCOST(4-byte integer)
    *               SQLDSLROW(4-byte integer)
    *               SQLDSNPM(4-byte integer)
    *               SQLDSNRS(4-byte integer)
    *               SQLDSRNS(4-byte integer)
    *               SQLDSDCOD(4-byte integer)
    *               SQLDSROWC(8-byte integer)
    *               SQLDSNROW(8-byte integer)
    *               SQLDSROWCS(8-byte integer)
    *               SQLDSACON(1-byte character fields)
    *               SQLDSACRH(1-byte character fields)
    *               SQLDSACRS(1-byte character fields)
    *               SQLDSACSL(1-byte character fields)
    *               SQLDSACSE(1-byte character fields)
    *               SQLDSACTY(1-byte character fields)
    *               SQLDSCERR(1-byte character fields)
    *               SQLDSMORE(1-byte character fields)
    */
    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_flg = 0;
    unsigned int ui_left_ddm_len = *p_ui_left_ddm_len;

    /* 根据协议SQLDIAGSTT必须大于等于1 */
    if (ui_left_ddm_len == 0)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    /* SQLDIAGSTT FLAG */
    i_ret = bytebuff_get_char(p_st_data, &u8_flg);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_left_ddm_len--;

    /* SQLDIAGSTT结束 */
    if (u8_flg == 0xFF)
    {
        *p_ui_left_ddm_len = ui_left_ddm_len;
        return APM_L7_ANALYZE_SUCC;
    }
    else if (u8_flg != 0x00)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /*
    *  根据协议可知：有(7 * (4-byte integer) + 3 * (8-byte integer)
    *  + 8 * (1-byte character fields))
    */
    if (ui_left_ddm_len < 7 * 4 + 3 * 8 + 8 * 1)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, 7 * 4 + 3 * 8 + 8 * 1);
    ui_left_ddm_len -= 7 * 4 + 3 * 8 + 8 * 1;

    *p_ui_left_ddm_len = ui_left_ddm_len;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析SQLDIAGGRP
*  ARGS     :  p_st_data (实际数据)
*           :  p_ui_left_ddm_len(遗留长度)
*           :  i_whole_flg(packet是否完整)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  遗留长度必须大于实际长度
*******************************************************************************/
int db2_parse_sqldiaggrp(Frbyte_Packet *p_st_data
                        , unsigned int *p_ui_left_ddm_len
                        , int i_whole_flg)
{
    /* SQLDIAGGRP格式
    *  SQLDIAGGRP = SQLDIAGSTT(参照SQLDIAGSTT)
    *               SQLDIAGCI(参照SQLDIAGCI)
    *               SQLDIAGCN(参照SQLDIAGCN)
    */
    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_flg = 0;
    unsigned int ui_left_ddm_len = *p_ui_left_ddm_len;

    /* 根据协议sqldiaggrp必须大于等于1 */
    if (ui_left_ddm_len == 0)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* SQLDIAGGRP FLAG */
    i_ret = bytebuff_get_char(p_st_data, &u8_flg);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_left_ddm_len--;

    /* SQLDIAGGRP结束 */
    if (u8_flg == 0xFF)
    {
        *p_ui_left_ddm_len = ui_left_ddm_len;
        return APM_L7_ANALYZE_SUCC;
    }
    else if (u8_flg != 0x00)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* SQLDIAGSTT */
    i_ret = db2_parse_sqldiagstt(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }

    /* SQLDIAGCI */
    i_ret = db2_parse_sqldiagci(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }

    /* SQLDIAGCN */
    i_ret = db2_parse_sqldiagcn(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return i_ret;
    }

    *p_ui_left_ddm_len = ui_left_ddm_len;
    return APM_L7_ANALYZE_SUCC;
}


/*******************************************************************************
*  FUNC     :  解析SQLCAXGRP
*  ARGS     :  p_st_private (DB2私有数据)
*           :  p_ui_left_ddm_len(遗留长度)
*           :  i_whole_flg(packet是否完整)
*           :  p_i_effect_rows(effect_rows)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  遗留长度必须大于实际数据长度
*******************************************************************************/
int db2_parse_sqlcaxgrp(L7session_db2_private *p_st_private
                       , unsigned int *p_ui_left_ddm_len
                       , int i_whole_flg
                       , unsigned int *p_ui_effect_rows)
{
    /* SQLCAXGRP格式:
    *  SQLCAXGRP = SQLERRD1(4-byte integer)
    *              SQLERRD2(4-byte integer)
    *              SQLERRD3(4-byte integer: effect rows)
    *              SQLERRD4(4-byte integer)
    *              SQLERRD5(4-byte integer)
    *              SQLERRD6(4-byte integer)
    *              SQLWARN0(1-byte character fields)
    *              SQLWARN1(1-byte character fields)
    *              SQLWARN2(1-byte character fields)
    *              SQLWARN3(1-byte character fields)
    *              SQLWARN4(1-byte character fields)
    *              SQLWARN5(1-byte character fields)
    *              SQLWARN6(1-byte character fields)
    *              SQLWARN7(1-byte character fields)
    *              SQLWARN8(1-byte character fields)
    *              SQLWARN9(1-byte character fields)
    *              SQLWARNA(1-byte character fields)
    *              SQLRDBNAME(A variable character string)
    *              SQLERRMSG_m(A variable character string)
    *              SQLERRMSG_s(A variable character string)
    */
    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_flg = 0;
    uint16_t u16_len = 0;
    uint32_t u32_effect_rows = 0;
    unsigned int ui_left_ddm_len = *p_ui_left_ddm_len;
    L7session_db2 *p_st_sess = p_st_private->p_st_sess;
    Frbyte_Packet *p_st_data = p_st_private->p_st_fragment->p_st_data;

    /* 根据协议sqlcaxgrp必须大于等于1 */
    if (ui_left_ddm_len == 0)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* SQLCAXGRP FLAG */
    i_ret = bytebuff_get_char(p_st_data, &u8_flg);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_left_ddm_len--;

    /* SQLCAXGRP结束 */
    if (u8_flg == 0xFF)
    {
        *p_ui_left_ddm_len = ui_left_ddm_len;
        return APM_L7_ANALYZE_SUCC;
    }
    else if (u8_flg != 0x00)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 至少有41(6*(4-byte integer) + 11*(1-byte character)
       + SQLRDBNAME + SQLERRMSG_m + SQLERRMSG_s) */
    if (ui_left_ddm_len < 41)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 跳过SQLERRD1,SQLERRD2 */
    bytebuff_skip(p_st_data, 4 + 4);

    /* 取得SQLERRD2(effect rows) */
    switch(p_st_sess->i_ser_typdef)
    {
        /* X86/VAX是字节序是little */
        case DRDA_TYPDEF_QTDSQLX86:
        case DRDA_TYPDEF_QTDSQLVAX:
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_effect_rows, BYTE_LITTLE_ENDIAN);
            break;

        /* 370/400/ASC是字节序是big */
        case DRDA_TYPDEF_QTDSQL370:
        case DRDA_TYPDEF_QTDSQL400:
        case DRDA_TYPDEF_QTDSQLASC:
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_effect_rows, BYTE_BIG_ENDIAN);
            break;

        default:
            i_ret = FR_FAIL;
            break;
    }
    /* 结果判定 */
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    *p_ui_effect_rows = u32_effect_rows;

    /* 跳过SQLERRD4,SQLERRD5,SQLERRD5,SQLWARN0~SQLWARNA */
    bytebuff_skip(p_st_data, 4 + 4 + 4 + 11 * 1);
    ui_left_ddm_len -= 4 * 6 + 11 * 1 + 2;

    /* SQLRDBNAME */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || ui_left_ddm_len < (unsigned int)(u16_len + 2))
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, u16_len);
    ui_left_ddm_len -= u16_len + 2;

    /* SQLERRMSG_m */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || ui_left_ddm_len < (unsigned int)(u16_len + 2))
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, u16_len);
    ui_left_ddm_len -= u16_len + 2;

    /* SQLERRMSG_s */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret != FR_SUCC || ui_left_ddm_len < u16_len)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    bytebuff_skip(p_st_data, u16_len);
    ui_left_ddm_len -= u16_len;

    *p_ui_left_ddm_len = ui_left_ddm_len;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析SQLCAGRP
*  ARGS     :  p_st_private (DB2私有数据)
*           :  p_ui_left_ddm_len(遗留长度)
*           :  i_whole_flg(packet是否完整)
*           :  p_i_sqlcode(SQLCODE)
*           :  p_sqlstate(SQLSTATE)
*           :  p_i_effect_rows(effect_rows)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_sqlstate必须是长度大于等于6
*******************************************************************************/
int db2_parse_sqlcagrp(L7session_db2_private *p_st_private
                      , int i_whole_flg
                      , int *p_i_sqlcode
                      , char *p_sqlstate
                      , unsigned long *p_ul_effect_rows)
{
    /* SQLCAGRP格式
    *  SQLCAGRP = SQLCODE(4-byte integer)
    *             SQLSTATE(5-byte character field)
    *             SQLERRPROC(8-byte character field)
    *             SQLCAXGRP(参照SQLCAXGRP)
    *             SQLDIAGGRP(参照SQLDIAGGRP)
    */

    int i_ret = APM_L7_ANALYZE_SUCC;
    uint8_t u8_flg = 0;
    uint32_t u32_sqlcode = 0;
    uint32_t u32_sqlcode1 = 0;
    uint32_t u32_sqlcode2 = 0;
    int i_sqlcode = 0;
    unsigned int ui_effect_rows = 0;
    L7session_db2 *p_st_sess = p_st_private->p_st_sess;
    L7_fragment_db2 *p_st_fragment = p_st_private->p_st_fragment;
    unsigned int ui_left_ddm_len = p_st_fragment->ui_left_ddm_len;
    Frbyte_Packet *p_st_data = p_st_fragment->p_st_data;

    /* 根据协议SQLCAGRP必须大于等于1 */
    if (ui_left_ddm_len == 0)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 长度不足 */
    if (ui_left_ddm_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        if (i_whole_flg == DB2_TRUE)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        else
        {
            return APM_L7_ANALYZE_TODO;
        }
    }

    /* SQLCAGRP FLAG */
    i_ret = bytebuff_get_char(p_st_data, &u8_flg);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    ui_left_ddm_len--;

    /* SQLCAGRP结束 */
    if (u8_flg == 0xFF)
    {
        p_st_fragment->ui_left_ddm_len = ui_left_ddm_len;
        return APM_L7_ANALYZE_SUCC;
    }
    else if (u8_flg != 0x00)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 至少有19(SQLCODE:4 + SQLSTATE:5 + SQLERRPROC:8 + SQLCAXGRP:1 + SQLCAXGRP:1) */
    if (ui_left_ddm_len < 19)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 取得SQLCODE */
    switch(p_st_sess->i_ser_typdef)
    {
        /* X86/VAX是字节序是little */
        case DRDA_TYPDEF_QTDSQLX86:
        case DRDA_TYPDEF_QTDSQLVAX:
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_sqlcode, BYTE_LITTLE_ENDIAN);
            break;

        /* 370/400/ASC是字节序是big */
        case DRDA_TYPDEF_QTDSQL370:
        case DRDA_TYPDEF_QTDSQL400:
        case DRDA_TYPDEF_QTDSQLASC:
            i_ret = bytebuff_get_int(p_st_data, 4, &u32_sqlcode, BYTE_BIG_ENDIAN);
            break;

        default:
            i_ret = FR_FAIL;
    }
    /* 结果判定 */
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    *p_i_sqlcode = (int)u32_sqlcode;

    /* 取得SQLSTATE */
    i_ret = bytebuff_get_bytes(p_st_data, p_sqlstate, 5);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 如果链接session信息是不定的，可以根据错误信息进行修正 */
    if (p_st_sess->i_confirmed_flg == DB2_FALSE)
    {
        if (memcmp(p_sqlstate, "00", 2) == 0  /* SQLSTATE为00开头表示完全成功 */
            || memcmp(p_sqlstate, "01", 2) == 0 /* SQLSTATE为01开头表示警告 */
            || memcmp(p_sqlstate, "02", 2) == 0) /* SQLSTATE为02开头表示无数据 */
        {
            /* 在上述情况下表示无错误，error code正常时大于0 */
            if (*p_i_sqlcode < 0)
            {
                /* 修正链接session信息 */
                switch (p_st_sess->i_ser_typdef)
                {
                    /* 小头的转大头 */
                    case DRDA_TYPDEF_QTDSQLX86:
                    case DRDA_TYPDEF_QTDSQLVAX:
                        u32_sqlcode1 = htonl(u32_sqlcode);
                        *p_i_sqlcode = (int)u32_sqlcode1;
                        p_st_sess->i_ser_typdef = DRDA_TYPDEF_QTDSQLASC;
                        break;

                    /* 大头的转小头 */
                    case DRDA_TYPDEF_QTDSQL370:
                    case DRDA_TYPDEF_QTDSQL400:
                    case DRDA_TYPDEF_QTDSQLASC:
                        u32_sqlcode1 = ntohl(u32_sqlcode);
                        *p_i_sqlcode = (int)u32_sqlcode1;
                        p_st_sess->i_ser_typdef = DRDA_TYPDEF_QTDSQLX86;
                        break;
                }
            }
        }
        else if (strchr("02345", *p_sqlstate)
                 && strchr("0123456789ABDEFKNU", *p_sqlstate + 1))
        {
            /* 在上述情况下表示有错误，error code正常时小于0 */
            if (*p_i_sqlcode > 0)
            {
                /* 修正链接session信息 */
                switch (p_st_sess->i_ser_typdef)
                {
                    /* 小头的转大头 */
                    case DRDA_TYPDEF_QTDSQLX86:
                    case DRDA_TYPDEF_QTDSQLVAX:
                        u32_sqlcode1 = htonl(u32_sqlcode);
                        *p_i_sqlcode = (int)u32_sqlcode1;
                        p_st_sess->i_ser_typdef = DRDA_TYPDEF_QTDSQLASC;
                        break;

                    /* 大头的转小头 */
                    case DRDA_TYPDEF_QTDSQL370:
                    case DRDA_TYPDEF_QTDSQL400:
                    case DRDA_TYPDEF_QTDSQLASC:
                        u32_sqlcode1 = ntohl(u32_sqlcode);
                        *p_i_sqlcode = (int)u32_sqlcode1;
                        p_st_sess->i_ser_typdef = DRDA_TYPDEF_QTDSQLX86;
                        break;
                }
            }
        }
        else
        {
            return APM_L7_ANALYZE_FAIL;
        }

        /* 上述修正还不够 */
        if (*p_i_sqlcode < -99999)
        {
            u32_sqlcode1 = *p_i_sqlcode;
            u32_sqlcode2 = ntohl(u32_sqlcode1);
            i_sqlcode = (int)u32_sqlcode2;
            if (i_sqlcode > -99999)
            {
                switch (p_st_sess->i_ser_typdef)
                {
                    /* 小头的转大头 */
                    case DRDA_TYPDEF_QTDSQLX86:
                    case DRDA_TYPDEF_QTDSQLVAX:
                        *p_i_sqlcode = i_sqlcode;
                        p_st_sess->i_ser_typdef = DRDA_TYPDEF_QTDSQLASC;
                        break;

                    /* 大头的转小头 */
                    case DRDA_TYPDEF_QTDSQL370:
                    case DRDA_TYPDEF_QTDSQL400:
                    case DRDA_TYPDEF_QTDSQLASC:
                        *p_i_sqlcode = i_sqlcode;
                        p_st_sess->i_ser_typdef = DRDA_TYPDEF_QTDSQLX86;
                        break;
                }
            }
        }
    }

    /* 跳过SQLERRPROC */
    bytebuff_skip(p_st_data, 8);
    ui_left_ddm_len -= 4 + 5 + 8;

    /* 解析SQLCAXGRP */
    i_ret = db2_parse_sqlcaxgrp(p_st_private, &ui_left_ddm_len
                               , i_whole_flg, &ui_effect_rows);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 解析sqldiaggrp */
    i_ret = db2_parse_sqldiaggrp(p_st_data, &ui_left_ddm_len, i_whole_flg);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    p_st_fragment->ui_left_ddm_len = ui_left_ddm_len;
    if (p_ul_effect_rows)
    {
        *p_ul_effect_rows = (unsigned long)ui_effect_rows;
    }
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析SQLDTAGRP
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(sqldtagrp长度)
*           :  p_lst_metadata(DB2 metadata list)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_st_metadata必须不为NULL
*******************************************************************************/
int db2_parse_sqldtagrp(Frbyte_Packet *p_st_data
                       , int i_whole_flg
                       , unsigned int ui_len
                       , Frlist_header *p_lst_metadata)
{
    int i_ret = FR_SUCC;
    uint8_t u8_data_type = 0;
    uint8_t u8_scale = 0;
    uint8_t u8_precision = 0;
    uint16_t u16_data_len = 0;
    Frlist_node *p_st_node = NULL;
    Sql_metadata_info *p_st_metadata = NULL;

    /* 根据协议长度为3n+3,所以肯定是3的倍数 */
    if (ui_len%3 && ui_len < 3)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 长度不足 */
    if (ui_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        if (i_whole_flg == DB2_TRUE)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        else
        {
            return APM_L7_ANALYZE_TODO;
        }
    }

    while (ui_len)
    {
        ui_len -= 3;
        /* 每3位的格式1byte的Data Type + 2byte(Data Length) */
        i_ret = bytebuff_get_char(p_st_data, &u8_data_type);
        if (i_ret != FR_SUCC)
        {
            frlist_remove_all(p_lst_metadata, frdb_metadata_node_free);
            return APM_L7_ANALYZE_FAIL;
        }

        /* 创建并设置DB2 metadata */
        p_st_metadata = (Sql_metadata_info *)frmalloc(sizeof(Sql_metadata_info));
        if (p_st_metadata == NULL)
        {
            frlist_remove_all(p_lst_metadata, frdb_metadata_node_free);
            return APM_L7_ANALYZE_FAIL;
        }

        /* 判断取到的数据类型 */
        switch (u8_data_type)
        {
            case DRDA_TYPE_FD:       //Fixed Decimal
            case DRDA_TYPE_NFD:      //Nullable Fixed Decimal
            case DRDA_TYPE_ZD:       //Zoned Decimal
            case DRDA_TYPE_NZD:      //Nullable Zoned Decimal
            case DRDA_TYPE_N:        //Numeric Character
            case DRDA_TYPE_NN:       //Nullable Numeric Character
                /* 取得scale */
                i_ret = bytebuff_get_char(p_st_data, &u8_scale);
                if (i_ret != FR_SUCC)
                {
                    frfree(p_st_metadata);
                    frlist_remove_all(p_lst_metadata, frdb_metadata_node_free);
                    return APM_L7_ANALYZE_FAIL;
                }
                /* 取得小数精度 */
                i_ret = bytebuff_get_char(p_st_data, &u8_precision);
                if (i_ret != FR_SUCC)
                {
                    frfree(p_st_metadata);
                    frlist_remove_all(p_lst_metadata, frdb_metadata_node_free);
                    return APM_L7_ANALYZE_FAIL;
                }
                p_st_metadata->ui_scale = u8_scale;
                p_st_metadata->ui_precision = u8_precision;
                break;

            case DRDA_TYPE_I4:       //4-byte Integer
            case DRDA_TYPE_NI4:      //Nullable 4-byte Integer
            case DRDA_TYPE_I2:       //2-byte Integer
            case DRDA_TYPE_NI2:      //Nullable 2-byte Integer
            case DRDA_TYPE_I1:       //1-byte Integer
            case DRDA_TYPE_NI1:      //Nullable 1-byte Integer
            case DRDA_TYPE_BF16:     //16-byte Basic Floating Point
            case DRDA_TYPE_NBF16:    //Nullable 16-byte Basic Floating Point
            case DRDA_TYPE_BF8:      //8-byte Basic Floating Point
            case DRDA_TYPE_NBF8:     //Nullable 8-byte Basic Floating Point
            case DRDA_TYPE_BF4:      //4-byte Basic Floating Point
            case DRDA_TYPE_NBF4:     //Nullable 4-byte Basic Floating Point
            case DRDA_TYPE_I8:       //Eight-byte Integer
            case DRDA_TYPE_NI8:      //Nullable Eight-byte Integer
            case DRDA_TYPE_RSL:      //Result Set Locator
            case DRDA_TYPE_NRSL:     //Nullable Result Set Locator
            case DRDA_TYPE_OBL:      //Large Object Bytes Locator
            case DRDA_TYPE_NOBL:     //Nullable Large Object Bytes Locator
            case DRDA_TYPE_OCL:      //Large Object Character Locator
            case DRDA_TYPE_NOCL:     //Nullable Large Object Character Locator
            case DRDA_TYPE_OCDL:     //Large Object Character DBCS Locator
            case DRDA_TYPE_NOCDL:    //Nullable Large Obj. Char. DBCS Locator
            case DRDA_TYPE_RI:       //Row Identifier
            case DRDA_TYPE_NRI:      //Nullable Row Identifier
            case DRDA_TYPE_D:        //Date
            case DRDA_TYPE_ND:       //Nullable Date
            case DRDA_TYPE_T:        //Time
            case DRDA_TYPE_NT:       //Nullable Time
            case DRDA_TYPE_TS:       //Timestamp
            case DRDA_TYPE_NTS:      //Nullable Timestamp
            case DRDA_TYPE_FB:       //Fixed Bytes
            case DRDA_TYPE_NFB:      //Nullable Fixed Bytes
            case DRDA_TYPE_VB:       //Variable Bytes
            case DRDA_TYPE_NVB:      //Nullable Variable Bytes
            case DRDA_TYPE_LVB:      //Long Variable Bytes
            case DRDA_TYPE_NLVB:     //Nullable Long Variable Bytes
            case DRDA_TYPE_NTB:      //Null-Terminated Bytes
            case DRDA_TYPE_NNTB:     //Nullable Null-Terminated Bytes
            case DRDA_TYPE_NTCS:     //Null-Terminated SBCS
            case DRDA_TYPE_NNTCS:    //Nullable Null-Terminated SBCS
            case DRDA_TYPE_FCS:      //Fixed Character SBCS
            case DRDA_TYPE_NFCS:     //Nullable Fixed Character SBCS
            case DRDA_TYPE_VCS:      //Variable Character SBCS
            case DRDA_TYPE_NVCS:     //Nullable Variable Character SBCS
            case DRDA_TYPE_LVCS:     //Long Variable Character SBCS
            case DRDA_TYPE_NLVCS:    //Nullable Long Variable Character SBCS
            case DRDA_TYPE_FCD:      //Fixed Character DBCS
            case DRDA_TYPE_NFCD:     //Nullable Fixed Character DBCS
            case DRDA_TYPE_VCD:      //Variable Character DBCS
            case DRDA_TYPE_NVCD:     //Nullable Variable Character DBCS
            case DRDA_TYPE_LVCD:     //Long Variable Character DBCS
            case DRDA_TYPE_NLVCD:    //Nullable Long Variable Character DBCS
            case DRDA_TYPE_FCM:      //Fixed Character Mixed
            case DRDA_TYPE_NFCM:     //Nullable Fixed Character Mixed
            case DRDA_TYPE_VCM:      //Variable Character Mixed
            case DRDA_TYPE_NVCM:     //Nullable Variable Character Mixed
            case DRDA_TYPE_LVCM:     //Long Variable Character Mixed
            case DRDA_TYPE_NLVCM:    //Nullable Long Variable Character Mixed
            case DRDA_TYPE_NTM:      //Null-Terminated Mixed
            case DRDA_TYPE_NNTM:     //Nullable Null-Terminated Mixed
            case DRDA_TYPE_PLB:      //Pascal L String Bytes
            case DRDA_TYPE_NPLB:     //Nullable Pascal L String Bytes
            case DRDA_TYPE_PLS:      //Pascal L String SBCS
            case DRDA_TYPE_NPLS:     //Nullable Pascal L String SBCS
            case DRDA_TYPE_PLM:      //Pascal L String Mixed
            case DRDA_TYPE_NPLM:     //Nullable Pascal L String Mixed
            case DRDA_TYPE_DLS:      //SBCS Datalink
            case DRDA_TYPE_NDLS:     //Nullable SBCS Datalink
            case DRDA_TYPE_DLM:      //Mixed-byte Datalink
            case DRDA_TYPE_NDLM:     //Nullable Mixed-byte Datalink
            case DRDA_TYPE_TSTZ:     //Timestamp with Time Zone
            case DRDA_TYPE_NTSTZ:    //Nullable Timestamp with Time Zone
            case DRDA_TYPE_CUR:      //Cursor Type
            case DRDA_TYPE_NCUR:     //Nullable Cursor Type
            case DRDA_TYPE_DFP:      //Decimal Floating Point
            case DRDA_TYPE_NDFP:     //Nullable Decimal Floating Point
            case DRDA_TYPE_XMLBIN:   //XML Binary
            case DRDA_TYPE_NXMLBIN:  //Nullable XML Binary
            case DRDA_TYPE_BL:       //Boolean
            case DRDA_TYPE_NBL:      //Nullable Boolean
            case DRDA_TYPE_FBIN:     //Fixed Binary
            case DRDA_TYPE_NFBIN:    //Nullable Fixed Binary
            case DRDA_TYPE_VBIN:     //Variable Binary
            case DRDA_TYPE_NVBIN:    //Nullable Variable Binary
            case DRDA_TYPE_XMLSIE:   //XML String Internal Encoding
            case DRDA_TYPE_NXMLSIE:  //Nullable XML String Internal Encoding
            case DRDA_TYPE_XMLSEE:   //XML String External Encoding
            case DRDA_TYPE_NXMLSEE:  //Nullable XML String External Encoding
            case DRDA_TYPE_OB:       //Large Object Bytes
            case DRDA_TYPE_NOB:      //Nullable Large Object Bytes
            case DRDA_TYPE_OCS:      //Large Object Character SBCS
            case DRDA_TYPE_NOCS:     //Nullable Large Object Character SBCS
            case DRDA_TYPE_OCD:      //Large Object Character DBCS
            case DRDA_TYPE_NOCD:     //Nullable Large Object Character DBCS
            case DRDA_TYPE_OCM:      //Large Object Character Mixed
            case DRDA_TYPE_NOCM:     //Nullable Large Object Character Mixed
                /* 取得data type的长度 */
                i_ret = bytebuff_get_short(p_st_data, 2, &u16_data_len, BYTE_BIG_ENDIAN);
                if (i_ret != FR_SUCC)
                {
                    frfree(p_st_metadata);
                    frlist_remove_all(p_lst_metadata, frdb_metadata_node_free);
                    return APM_L7_ANALYZE_FAIL;
                }
                p_st_metadata->ui_len = u16_data_len;
                break;

            default:
                frdbg("Unknow data type!\n");
                frfree(p_st_metadata);
                frlist_remove_all(p_lst_metadata, frdb_metadata_node_free);
                return APM_L7_ANALYZE_FAIL;
        }

        p_st_metadata->i_data_type = u8_data_type;

        /* 创建并追加节点 */
        p_st_node = frlist_node_create(p_st_metadata);
        if (p_st_node == NULL)
        {
            frfree(p_st_metadata);
            frlist_remove_all(p_lst_metadata, frdb_metadata_node_free);
            return APM_L7_ANALYZE_FAIL;
        }
        p_st_metadata = NULL;
        frlist_push(p_lst_metadata, p_st_node);
    }

    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析一列数据
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  i_typdef(数据类型)
*           :  p_lst_metadata(DB2 metadata list)
*           :  pp_lst_bind(DB2 bind list)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_lst_bind必须不为NULL
*******************************************************************************/
int db2_parse_one_cloum(Frbyte_Packet *p_st_data
                       , int i_whole_flg
                       , int i_typdef
                       , unsigned int *p_ui_len
                       , Frlist_header *p_lst_metadata
                       , Sql_field_bind **pp_lst_bind)
{
    int i_ret = FR_SUCC;
    uint8_t u8_flg = 0;
    //int i_loop = 0;
    unsigned int ui_len = *p_ui_len;
    Frlist_node *p_st_node = NULL;
    Frdata_field *p_st_frdata = NULL;
    Sql_field_bind *p_lst_bind = NULL;
    Frlist_node *p_st_node_data = NULL;
    Sql_metadata_info *p_st_metadata = NULL;

    /* 创建bind list */
    p_lst_bind = (Sql_field_bind *)frmalloc(sizeof(Sql_field_bind));
    if (p_lst_bind == NULL)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    memset(p_lst_bind, 0x0, sizeof(Sql_field_bind));

    p_st_node = FRLIST_FIRST_NODE(p_lst_metadata);
    while (p_st_node)
    {
        p_st_metadata = (Sql_metadata_info *)FRLIST_GET_NODE_DATA(p_st_node);

        if (ui_len == 0)
        {
            frdb_field_bind_free(&p_lst_bind);
            return APM_L7_ANALYZE_FAIL;
        }
        /* 数据不足 */
        if (bytebuff_remaining(p_st_data) <= 0)
        {
            goto unknow;
        }

        /* 将数据类型与0x01想与判断该类型是否是Nullable */
        if (p_st_metadata->i_data_type & 0x01)
        {
            /* 取得第一个字节由此判断该字段是否为NULL */
            i_ret = bytebuff_get_char(p_st_data, &u8_flg);
            if (i_ret != FR_SUCC)
            {
                frdb_field_bind_free(&p_lst_bind);
                return APM_L7_ANALYZE_FAIL;
            }
            i_ret = APM_L7_ANALYZE_SUCC;
            ui_len--;
        }
        else
        {
            u8_flg = 0;
        }

        /* 创建frdata以及其参数名 */
        p_st_frdata = (Frdata_field *)frmalloc(sizeof(Frdata_field));
        if (p_st_frdata == NULL)
        {
            frdb_field_bind_free(&p_lst_bind);
            return APM_L7_ANALYZE_FAIL;
        }
        memset(p_st_frdata, 0x0, sizeof(Frdata_field));
        //p_st_frdata->p_field_name = __db2_param_name(i_loop++);
        //p_st_frdata->i_field_index = i_loop;
        //if (p_st_frdata->p_field_name == NULL)
        //{
        //    frfree(p_st_frdata);
        //    frdb_field_bind_free(&p_lst_bind);
        //    return APM_L7_ANALYZE_FAIL;
        //}

        switch (p_st_metadata->i_data_type)
        {
            /* 取得int型数据 */
            case DRDA_TYPE_I4:       //4-byte Integer
            case DRDA_TYPE_NI4:      //Nullable 4-byte Integer
                p_st_frdata->em_data_type = FRINT;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_4byte_int(p_st_data, i_whole_flg
                                         , i_typdef, &ui_len, p_st_frdata);
                }
                break;

            /* 取得short型数据 */
            case DRDA_TYPE_I2:       //2-byte Integer
            case DRDA_TYPE_NI2:      //Nullable 2-byte Integer
                p_st_frdata->em_data_type = FRINT;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_2byte_int(p_st_data, i_whole_flg
                                         , i_typdef, &ui_len, p_st_frdata);
                }
                break;

            /* 取得byte型数据 */
            case DRDA_TYPE_I1:       //1-byte Integer
            case DRDA_TYPE_NI1:      //Nullable 1-byte Integer
                p_st_frdata->em_data_type = FRINT;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_1byte_int(p_st_data, i_whole_flg
                                         , &ui_len, p_st_frdata);
                }
                break;

            /* 取得Floating型数据 */
            case DRDA_TYPE_BF16:     //16-byte Basic Floating Point
            case DRDA_TYPE_NBF16:    //Nullable 16-byte Basic Floating Point
                p_st_frdata->em_data_type = FRFLOAT;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_16byte_float(p_st_data, i_whole_flg
                                            , i_typdef, &ui_len, p_st_frdata);
                }
                break;

            /* 取得Floating型数据 */
            case DRDA_TYPE_BF8:      //8-byte Basic Floating Point
            case DRDA_TYPE_NBF8:     //Nullable 8-byte Basic Floating Point
                p_st_frdata->em_data_type = FRFLOAT;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_8byte_float(p_st_data, i_whole_flg
                                           , i_typdef, &ui_len, p_st_frdata);
                }
                break;

            /* 取得Floating型数据 */
            case DRDA_TYPE_BF4:      //4-byte Basic Floating Point
            case DRDA_TYPE_NBF4:     //Nullable 4-byte Basic Floating Point
                p_st_frdata->em_data_type = FRFLOAT;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_4byte_float(p_st_data, i_whole_flg
                                           , i_typdef, &ui_len, p_st_frdata);
                }
                break;

            /* 取得Decimal型数据 */
            case DRDA_TYPE_FD:       //Fixed Decimal
            case DRDA_TYPE_NFD:      //Nullable Fixed Decimal
                p_st_frdata->em_data_type = FRDOUBLE;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_fixed_dec(p_st_data, i_whole_flg
                                         , p_st_metadata->ui_scale
                                         , p_st_metadata->ui_precision
                                         , &ui_len, p_st_frdata);
                }
                break;

            /* 取得Zoned Decimal型数据 */
            case DRDA_TYPE_ZD:       //Zoned Decimal
            case DRDA_TYPE_NZD:      //Nullable Zoned Decimal
                p_st_frdata->em_data_type = FRDOUBLE;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_zoned_dec(p_st_data, i_whole_flg
                                         , p_st_metadata->ui_scale
                                         , p_st_metadata->ui_precision
                                         , &ui_len, p_st_frdata);
                }
                break;

            /* 取得long型数据 */
            case DRDA_TYPE_I8:       //Eight-byte Integer
            case DRDA_TYPE_NI8:      //Nullable Eight-byte Integer
                p_st_frdata->em_data_type = FRLONG;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_8byte_long(p_st_data, i_whole_flg
                                          , i_typdef, &ui_len, p_st_frdata);
                }
                break;

            /* 取得时间型数据 */
            case DRDA_TYPE_D:        //Date
            case DRDA_TYPE_ND:       //Nullable Date
            case DRDA_TYPE_T:        //Time
            case DRDA_TYPE_NT:       //Nullable Time
            case DRDA_TYPE_TS:       //Timestamp
            case DRDA_TYPE_NTS:      //Nullable Timestamp
                p_st_frdata->em_data_type = FRTIME;
                if (u8_flg != 0xFF)
                {
                    //取得时间类型值
                    i_ret = db2_get_fs_chars(p_st_data, i_whole_flg, &ui_len
                                             , p_st_metadata->ui_len
                                             , p_st_frdata);
                }
                break;

            /* 跳过bytes数据 */
            case DRDA_TYPE_FB:       //Fixed Bytes
            case DRDA_TYPE_NFB:      //Nullable Fixed Bytes
                p_st_frdata->em_data_type = FRBLOB;
                if (u8_flg != 0xFF)
                {
                    /* 跳过固定长度的单字节字符 */
                    i_ret = db2_skip_bytes(p_st_data, i_whole_flg, &ui_len
                                          , p_st_metadata->ui_len);
                    if (p_st_frdata->p_field_value == NULL)
                    {
                        p_st_frdata->p_field_value = frstrdup("Bytes");
                    }
                }
                break;

            /* 跳过bytes数据 */
            case DRDA_TYPE_VB:       //Variable Bytes
            case DRDA_TYPE_NVB:      //Nullable Variable Bytes
            case DRDA_TYPE_LVB:      //Long Variable Bytes
            case DRDA_TYPE_NLVB:     //Nullable Long Variable Bytes
                p_st_frdata->em_data_type = FRBLOB;
                if (u8_flg != 0xFF)
                {
                    /* 跳过不固定长度的单字节字符 */
                    i_ret = db2_skip_varbytes(p_st_data, i_whole_flg
                                             , &ui_len, DB2_SINGLE);
                    if (p_st_frdata->p_field_value == NULL)
                    {
                        p_st_frdata->p_field_value = frstrdup("Bytes");
                    }
                }
                break;

            /* 取得字符串 */
            case DRDA_TYPE_FCD:      //Fixed Character DBCS
            case DRDA_TYPE_NFCD:     //Nullable Fixed Character DBCS
                p_st_frdata->em_data_type = FRSTRING;
                if (u8_flg != 0xFF)
                {
                    /* 取得固定长度的双字节字符 */
                    i_ret = db2_get_fd_chars(p_st_data, i_whole_flg, i_typdef
                                             , &ui_len, p_st_metadata->ui_len
                                             , p_st_frdata);
                }
                break;

            /* 取得字符串 */
            case DRDA_TYPE_VCD:      //Variable Character DBCS
            case DRDA_TYPE_NVCD:     //Nullable Variable Character DBCS
            case DRDA_TYPE_LVCD:     //Long Variable Character DBCS
            case DRDA_TYPE_NLVCD:    //Nullable Long Variable Character DBCS
                p_st_frdata->em_data_type = FRSTRING;
                if (u8_flg != 0xFF)
                {
                    /* 取得不固定长度的双单字节字符 */
                    i_ret = db2_get_vd_chars(p_st_data, i_whole_flg, i_typdef
                                            , &ui_len, p_st_frdata);
                }
                break;

            /* 取得字符串 */
            case DRDA_TYPE_FCM:      //Fixed Character Mixed
            case DRDA_TYPE_NFCM:     //Nullable Fixed Character Mixed
            case DRDA_TYPE_FCS:      //Fixed Character SBCS
            case DRDA_TYPE_NFCS:     //Nullable Fixed Character SBCS
                p_st_frdata->em_data_type = FRSTRING;
                if (u8_flg != 0xFF)
                {
                    /* 取得固定长度的单字节字符 */
                    i_ret = db2_get_fs_chars(p_st_data, i_whole_flg, &ui_len
                                             , p_st_metadata->ui_len
                                             , p_st_frdata);
                }
                break;

            /* 取得字符串 */
            case DRDA_TYPE_VCM:      //Variable Character Mixed
            case DRDA_TYPE_NVCM:     //Nullable Variable Character Mixed
            case DRDA_TYPE_LVCM:     //Long Variable Character Mixed
            case DRDA_TYPE_NLVCM:    //Nullable Long Variable Character Mixed
            case DRDA_TYPE_VCS:      //Variable Character SBCS
            case DRDA_TYPE_NVCS:     //Nullable Variable Character SBCS
            case DRDA_TYPE_LVCS:     //Long Variable Character SBCS
            case DRDA_TYPE_NLVCS:    //Nullable Long Variable Character SBCS
                p_st_frdata->em_data_type = FRSTRING;
                if (u8_flg != 0xFF)
                {
                    /* 取得不固定长度的单字节字符 */
                    i_ret = db2_get_vs_chars(p_st_data, i_whole_flg
                                            , &ui_len, p_st_frdata);
                }
                break;

            case DRDA_TYPE_FBIN:     //Fixed Binary
            case DRDA_TYPE_NFBIN:    //Nullable Fixed Binary
                p_st_frdata->em_data_type = FRBLOB;
                if (u8_flg != 0xFF)
                {
                    /* 根据截取到的数据包实际数据存在EXTDTA中,此处占用10描述个字节 */
                    i_ret = db2_skip_bytes(p_st_data, i_whole_flg, &ui_len
                                           , p_st_metadata->ui_len);
                    if (p_st_frdata->p_field_value == NULL)
                    {
                        p_st_frdata->p_field_value = frstrdup("Binary");
                    }
                }
                break;

            case DRDA_TYPE_VBIN:     //Variable Binary
            case DRDA_TYPE_NVBIN:    //Nullable Variable Binary
                p_st_frdata->em_data_type = FRBLOB;
                if (u8_flg != 0xFF)
                {
                    /* 根据截取到的数据包实际数据存在EXTDTA中,此处占用10描述个字节 */
                    i_ret = db2_skip_varbytes(p_st_data, i_whole_flg
                                             , &ui_len, DB2_SINGLE);
                    if (p_st_frdata->p_field_value == NULL)
                    {
                        p_st_frdata->p_field_value = frstrdup("Binary");
                    }
                }
                break;

            case DRDA_TYPE_XMLSIE:   //XML String Internal Encoding
            case DRDA_TYPE_NXMLSIE:  //Nullable XML String Internal Encoding
            case DRDA_TYPE_XMLSEE:   //XML String External Encoding
            case DRDA_TYPE_NXMLSEE:  //Nullable XML String External Encoding
                p_st_frdata->em_data_type = FRCLOB;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_skip_lob(p_st_data, i_whole_flg, &ui_len, DB2_SINGLE);
                    if (p_st_frdata->p_field_value == NULL)
                    {
                        p_st_frdata->p_field_value = frstrdup("XML");
                    }
                }
                break;

            case DRDA_TYPE_OCD:      //Large Object Character DBCS
            case DRDA_TYPE_NOCD:     //Nullable Large Object Character DBCS
                /* 大数据不取值 */
                p_st_frdata->em_data_type = FRCLOB;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_skip_lob(p_st_data, i_whole_flg, &ui_len, DB2_DOUBLE);
                    if (p_st_frdata->p_field_value == NULL)
                    {
                        p_st_frdata->p_field_value = frstrdup("Large Object Character DBCS");
                    }
                }
                break;

            case DRDA_TYPE_OB:       //Large Object Bytes
            case DRDA_TYPE_NOB:      //Nullable Large Object Bytes
                p_st_frdata->em_data_type = FRBLOB;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_skip_lob(p_st_data, i_whole_flg, &ui_len, DB2_SINGLE);
                    if (p_st_frdata->p_field_value == NULL)
                    {
                        p_st_frdata->p_field_value = frstrdup("Large Object Bytes");
                    }
                }
                break;

            case DRDA_TYPE_OCS:      //Large Object Character SBCS
            case DRDA_TYPE_NOCS:     //Nullable Large Object Character SBCS
            case DRDA_TYPE_OCM:      //Large Object Character Mixed
            case DRDA_TYPE_NOCM:     //Nullable Large Object Character Mixed
                p_st_frdata->em_data_type = FRCLOB;
                if (u8_flg != 0xFF)
                {
                    i_ret = db2_skip_lob(p_st_data, i_whole_flg, &ui_len, DB2_SINGLE);
                    if (p_st_frdata->p_field_value == NULL)
                    {
                        p_st_frdata->p_field_value = frstrdup("Large Object Character");
                    }
                }
                break;

            /* 未解析到的数据类型 */
            case DRDA_TYPE_N:        //Numeric Character
            case DRDA_TYPE_NN:       //Nullable Numeric Character
            case DRDA_TYPE_RI:       //Row Identifier
            case DRDA_TYPE_NRI:      //Nullable Row Identifier
            case DRDA_TYPE_RSL:      //Result Set Locator
            case DRDA_TYPE_NRSL:     //Nullable Result Set Locator
            case DRDA_TYPE_OBL:      //Large Object Bytes Locator
            case DRDA_TYPE_NOBL:     //Nullable Large Object Bytes Locator
            case DRDA_TYPE_OCL:      //Large Object Character Locator
            case DRDA_TYPE_NOCL:     //Nullable Large Object Character Locator
            case DRDA_TYPE_OCDL:     //Large Object Character DBCS Locator
            case DRDA_TYPE_NOCDL:    //Nullable Large Obj. Char. DBCS Locator
            case DRDA_TYPE_NTM:      //Null-Terminated Mixed
            case DRDA_TYPE_NNTM:     //Nullable Null-Terminated Mixed
            case DRDA_TYPE_PLB:      //Pascal L String Bytes
            case DRDA_TYPE_NPLB:     //Nullable Pascal L String Bytes
            case DRDA_TYPE_PLS:      //Pascal L String SBCS
            case DRDA_TYPE_NPLS:     //Nullable Pascal L String SBCS
            case DRDA_TYPE_PLM:      //Pascal L String Mixed
            case DRDA_TYPE_NPLM:     //Nullable Pascal L String Mixed
            case DRDA_TYPE_DLS:      //SBCS Datalink
            case DRDA_TYPE_NDLS:     //Nullable SBCS Datalink
            case DRDA_TYPE_DLM:      //Mixed-byte Datalink
            case DRDA_TYPE_NDLM:     //Nullable Mixed-byte Datalink
            case DRDA_TYPE_TSTZ:     //Timestamp with Time Zone
            case DRDA_TYPE_NTSTZ:    //Nullable Timestamp with Time Zone
            case DRDA_TYPE_CUR:      //Cursor Type
            case DRDA_TYPE_NCUR:     //Nullable Cursor Type
            case DRDA_TYPE_DFP:      //Decimal Floating Point
            case DRDA_TYPE_NDFP:     //Nullable Decimal Floating Point
            case DRDA_TYPE_XMLBIN:   //XML Binary
            case DRDA_TYPE_NXMLBIN:  //Nullable XML Binary
            case DRDA_TYPE_BL:       //Boolean
            case DRDA_TYPE_NBL:      //Nullable Boolean
            case DRDA_TYPE_NTB:      //Null-Terminated Bytes
            case DRDA_TYPE_NNTB:     //Nullable Null-Terminated Bytes
            case DRDA_TYPE_NTCS:     //Null-Terminated SBCS
            case DRDA_TYPE_NNTCS:    //Nullable Null-Terminated SBCS
                frdbg("TODO, [%02X]need to parse!\n", p_st_metadata->i_data_type);
                i_ret = APM_L7_ANALYZE_FAIL;
                break;

            default:
                frdbg("Unknow data type!\n");
                i_ret = APM_L7_ANALYZE_FAIL;
                break;
        }

        //FRINT/FRLONG/FRFLOAT/FRDOUBLE/FRSTRING/FRTIME/FRCLOB/FRBLOB
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            db2_frdata_free(&p_st_frdata);
            frdb_field_bind_free(&p_lst_bind);
            return i_ret;
        }

        /* 创建并追加节点 */
        p_st_node_data = frlist_node_create(p_st_frdata);
        if (p_st_node_data == NULL)
        {
            db2_frdata_free(&p_st_frdata);
            frdb_field_bind_free(&p_lst_bind);
            return APM_L7_ANALYZE_FAIL;
        }
        frlist_push(&p_lst_bind->st_field_list, p_st_node_data);
        /* 取得下一个节点 */
        p_st_node = FRLIST_NEXT_NODE(p_st_node);
    }

    *p_ui_len = ui_len;
    *pp_lst_bind = p_lst_bind;
    return APM_L7_ANALYZE_SUCC;

unknow:
    frdb_field_bind_free(&p_lst_bind);
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  跳过一列数据
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  i_typdef(数据类型)
*           :  p_lst_metadata(DB2 metadata list)
*           :  pp_lst_bind(DB2 bind list)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_lst_bind必须不为NULL
*******************************************************************************/
int db2_skip_one_cloum(Frbyte_Packet *p_st_data
                       , int i_whole_flg
                       , unsigned int *p_ui_len
                       , Frlist_header *p_lst_metadata)
{
    int i_ret = FR_SUCC;
    uint8_t u8_flg = 0;
    unsigned int ui_len = *p_ui_len;
    unsigned int ui_len_tmp = 0;
    Frlist_node *p_st_node = NULL;
    Sql_metadata_info *p_st_metadata = NULL;

    p_st_node = FRLIST_FIRST_NODE(p_lst_metadata);
    while (p_st_node)
    {
        p_st_metadata = (Sql_metadata_info *)FRLIST_GET_NODE_DATA(p_st_node);

        if (ui_len == 0)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        /* 数据不足 */
        if (bytebuff_remaining(p_st_data) <= 0)
        {
            goto unknow;
        }

        /* 将数据类型与0x01想与判断该类型是否是Nullable */
        if (p_st_metadata->i_data_type & 0x01)
        {
            /* 取得第一个字节由此判断该Nullable字段是否为NULL */
            i_ret = bytebuff_get_char(p_st_data, &u8_flg);
            if (i_ret != FR_SUCC)
            {
                return APM_L7_ANALYZE_FAIL;
            }
            ui_len--;
            if (u8_flg == 0xFF)
            {
                /* 取得下一个节点 */
                p_st_node = FRLIST_NEXT_NODE(p_st_node);
                continue;
            }
        }

        switch (p_st_metadata->i_data_type)
        {
            /* 跳过4byte型数据 */
            case DRDA_TYPE_I4:       //4-byte Integer
            case DRDA_TYPE_NI4:      //Nullable 4-byte Integer
            case DRDA_TYPE_BF4:      //4-byte Basic Floating Point
            case DRDA_TYPE_NBF4:     //Nullable 4-byte Basic Floating Point
                i_ret = db2_skip_bytes(p_st_data, i_whole_flg, &ui_len, 4);
                break;

            /* 跳过short型数据 */
            case DRDA_TYPE_I2:       //2-byte Integer
            case DRDA_TYPE_NI2:      //Nullable 2-byte Integer
                i_ret = db2_skip_bytes(p_st_data, i_whole_flg, &ui_len, 2);
                break;

            /* 跳过byte型数据 */
            case DRDA_TYPE_I1:       //1-byte Integer
            case DRDA_TYPE_NI1:      //Nullable 1-byte Integer
                i_ret = db2_skip_bytes(p_st_data, i_whole_flg, &ui_len, 1);
                break;

            /* 跳过16byte型数据 */
            case DRDA_TYPE_BF16:     //16-byte Basic Floating Point
            case DRDA_TYPE_NBF16:    //Nullable 16-byte Basic Floating Point
                i_ret = db2_skip_bytes(p_st_data, i_whole_flg, &ui_len, 16);
                break;

            /* 跳过8byte型数据 */
            case DRDA_TYPE_I8:       //Eight-byte Integer
            case DRDA_TYPE_NI8:      //Nullable Eight-byte Integer
            case DRDA_TYPE_BF8:      //8-byte Basic Floating Point
            case DRDA_TYPE_NBF8:     //Nullable 8-byte Basic Floating Point
                i_ret = db2_skip_bytes(p_st_data, i_whole_flg, &ui_len, 8);
                break;

            /* 跳过固定长度数据 */
            case DRDA_TYPE_FD:       //Fixed Decimal
            case DRDA_TYPE_NFD:      //Nullable Fixed Decimal
                ui_len_tmp = (p_st_metadata->ui_scale)/2 + 1;
                i_ret = db2_skip_bytes(p_st_data, i_whole_flg, &ui_len, ui_len_tmp);
                break;

            /* 跳过固定长度数据 */
            case DRDA_TYPE_ZD:       //Zoned Decimal
            case DRDA_TYPE_NZD:      //Nullable Zoned Decimal
                i_ret = db2_skip_bytes(p_st_data, i_whole_flg, &ui_len
                                      , p_st_metadata->ui_scale);
                break;

            /* 跳过固定长度数据 */
            case DRDA_TYPE_D:        //Date
            case DRDA_TYPE_ND:       //Nullable Date
            case DRDA_TYPE_T:        //Time
            case DRDA_TYPE_NT:       //Nullable Time
            case DRDA_TYPE_TS:       //Timestamp
            case DRDA_TYPE_NTS:      //Nullable Timestamp
            case DRDA_TYPE_FB:       //Fixed Bytes
            case DRDA_TYPE_NFB:      //Nullable Fixed Bytes
            case DRDA_TYPE_FBIN:     //Fixed Binary
            case DRDA_TYPE_NFBIN:    //Nullable Fixed Binary
            case DRDA_TYPE_FCM:      //Fixed Character Mixed
            case DRDA_TYPE_NFCM:     //Nullable Fixed Character Mixed
            case DRDA_TYPE_FCS:      //Fixed Character SBCS
            case DRDA_TYPE_NFCS:     //Nullable Fixed Character SBCS
                i_ret = db2_skip_bytes(p_st_data, i_whole_flg, &ui_len
                                      , p_st_metadata->ui_len);
                break;

            /* 跳过不固定长度数据 */
            case DRDA_TYPE_VB:       //Variable Bytes
            case DRDA_TYPE_NVB:      //Nullable Variable Bytes
            case DRDA_TYPE_LVB:      //Long Variable Bytes
            case DRDA_TYPE_NLVB:     //Nullable Long Variable Bytes
            case DRDA_TYPE_VCM:      //Variable Character Mixed
            case DRDA_TYPE_NVCM:     //Nullable Variable Character Mixed
            case DRDA_TYPE_LVCM:     //Long Variable Character Mixed
            case DRDA_TYPE_NLVCM:    //Nullable Long Variable Character Mixed
            case DRDA_TYPE_VCS:      //Variable Character SBCS
            case DRDA_TYPE_NVCS:     //Nullable Variable Character SBCS
            case DRDA_TYPE_LVCS:     //Long Variable Character SBCS
            case DRDA_TYPE_NLVCS:    //Nullable Long Variable Character SBCS
            case DRDA_TYPE_VBIN:     //Variable Binary
            case DRDA_TYPE_NVBIN:    //Nullable Variable Binary
                i_ret = db2_skip_varbytes(p_st_data, i_whole_flg
                                          , &ui_len, DB2_SINGLE);
                break;

            /* 跳过固定长度双字节数据 */
            case DRDA_TYPE_FCD:      //Fixed Character DBCS
            case DRDA_TYPE_NFCD:     //Nullable Fixed Character DBCS
                i_ret = db2_skip_bytes(p_st_data, i_whole_flg, &ui_len
                                      , (p_st_metadata->ui_len) * 2);
                break;

            /* 跳过不固定长度双字节数据 */
            case DRDA_TYPE_VCD:      //Variable Character DBCS
            case DRDA_TYPE_NVCD:     //Nullable Variable Character DBCS
            case DRDA_TYPE_LVCD:     //Long Variable Character DBCS
            case DRDA_TYPE_NLVCD:    //Nullable Long Variable Character DBCS
                i_ret = db2_skip_varbytes(p_st_data, i_whole_flg
                                          , &ui_len, DB2_DOUBLE);
                break;

            case DRDA_TYPE_OCD:      //Large Object Character DBCS
            case DRDA_TYPE_NOCD:     //Nullable Large Object Character DBCS
                i_ret = db2_skip_lob(p_st_data, i_whole_flg, &ui_len, DB2_DOUBLE);
                break;

            case DRDA_TYPE_XMLSIE:   //XML String Internal Encoding
            case DRDA_TYPE_NXMLSIE:  //Nullable XML String Internal Encoding
            case DRDA_TYPE_XMLSEE:   //XML String External Encoding
            case DRDA_TYPE_NXMLSEE:  //Nullable XML String External Encoding
            case DRDA_TYPE_OB:       //Large Object Bytes
            case DRDA_TYPE_NOB:      //Nullable Large Object Bytes
            case DRDA_TYPE_OCS:      //Large Object Character SBCS
            case DRDA_TYPE_NOCS:     //Nullable Large Object Character SBCS
            case DRDA_TYPE_OCM:      //Large Object Character Mixed
            case DRDA_TYPE_NOCM:     //Nullable Large Object Character Mixed
                i_ret = db2_skip_lob(p_st_data, i_whole_flg, &ui_len, DB2_SINGLE);
                break;

            /* 未解析到的数据类型 */
            case DRDA_TYPE_N:        //Numeric Character
            case DRDA_TYPE_NN:       //Nullable Numeric Character
            case DRDA_TYPE_RI:       //Row Identifier
            case DRDA_TYPE_NRI:      //Nullable Row Identifier
            case DRDA_TYPE_RSL:      //Result Set Locator
            case DRDA_TYPE_NRSL:     //Nullable Result Set Locator
            case DRDA_TYPE_OBL:      //Large Object Bytes Locator
            case DRDA_TYPE_NOBL:     //Nullable Large Object Bytes Locator
            case DRDA_TYPE_OCL:      //Large Object Character Locator
            case DRDA_TYPE_NOCL:     //Nullable Large Object Character Locator
            case DRDA_TYPE_OCDL:     //Large Object Character DBCS Locator
            case DRDA_TYPE_NOCDL:    //Nullable Large Obj. Char. DBCS Locator
            case DRDA_TYPE_NTM:      //Null-Terminated Mixed
            case DRDA_TYPE_NNTM:     //Nullable Null-Terminated Mixed
            case DRDA_TYPE_PLB:      //Pascal L String Bytes
            case DRDA_TYPE_NPLB:     //Nullable Pascal L String Bytes
            case DRDA_TYPE_PLS:      //Pascal L String SBCS
            case DRDA_TYPE_NPLS:     //Nullable Pascal L String SBCS
            case DRDA_TYPE_PLM:      //Pascal L String Mixed
            case DRDA_TYPE_NPLM:     //Nullable Pascal L String Mixed
            case DRDA_TYPE_DLS:      //SBCS Datalink
            case DRDA_TYPE_NDLS:     //Nullable SBCS Datalink
            case DRDA_TYPE_DLM:      //Mixed-byte Datalink
            case DRDA_TYPE_NDLM:     //Nullable Mixed-byte Datalink
            case DRDA_TYPE_TSTZ:     //Timestamp with Time Zone
            case DRDA_TYPE_NTSTZ:    //Nullable Timestamp with Time Zone
            case DRDA_TYPE_CUR:      //Cursor Type
            case DRDA_TYPE_NCUR:     //Nullable Cursor Type
            case DRDA_TYPE_DFP:      //Decimal Floating Point
            case DRDA_TYPE_NDFP:     //Nullable Decimal Floating Point
            case DRDA_TYPE_XMLBIN:   //XML Binary
            case DRDA_TYPE_NXMLBIN:  //Nullable XML Binary
            case DRDA_TYPE_BL:       //Boolean
            case DRDA_TYPE_NBL:      //Nullable Boolean
            case DRDA_TYPE_NTB:      //Null-Terminated Bytes
            case DRDA_TYPE_NNTB:     //Nullable Null-Terminated Bytes
            case DRDA_TYPE_NTCS:     //Null-Terminated SBCS
            case DRDA_TYPE_NNTCS:    //Nullable Null-Terminated SBCS
                frdbg("TODO, [%02X]need to parse!\n", p_st_metadata->i_data_type);
                return APM_L7_ANALYZE_FAIL;

            default:
                frdbg("Unknow data type!\n");
                return APM_L7_ANALYZE_FAIL;
        }

        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            return i_ret;
        }
        /* 取得下一个节点 */
        p_st_node = FRLIST_NEXT_NODE(p_st_node);
    }

    *p_ui_len = ui_len;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  解析数据
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_len(数据长度)
*           :  i_typdef(type define)
*           :  p_lst_metadata(DB2 metadata list)
*           :  p_lst_bind(DB2 bind list)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_lst_bind必须不为NULL
*******************************************************************************/
int db2_get_fetch_rows(L7session_db2_private *p_st_private
                      , int i_whole_flg
                      , Frlist_header *p_lst_metadata
                      , unsigned long *p_ul_rows
                      , Db2_req_cmd *p_st_cmd_cp)
{
    int i_ret = FR_SUCC;
    uint8_t u8_flg = 0;
    int i_sqlcode = 0;
    unsigned int ui_len_org = 0;
    unsigned long ul_rows = 0;
    char arr_sqlstate[6] = {0};
    L7_fragment_db2 *p_st_fragment = p_st_private->p_st_fragment;
    Frbyte_Packet *p_st_data = p_st_fragment->p_st_data;

    ui_len_org = p_st_fragment->ui_left_ddm_len;
    while (p_st_fragment->ui_left_ddm_len)
    {
        /* 跳过sqlcagrp */
        i_ret = db2_parse_sqlcagrp(p_st_private, i_whole_flg
                                  , &i_sqlcode, arr_sqlstate, NULL);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            return i_ret;
        }

        if (p_st_fragment->ui_left_ddm_len == 0)
        {
            p_st_fragment->i_req_resp_cp = DRDA_CP_NULL;
            *p_ul_rows = ul_rows;
            return APM_L7_ANALYZE_SUCC;
        }

        p_st_fragment->ui_left_ddm_len--;
        /* 数据不足 */
        if (bytebuff_remaining(p_st_data) <= 0)
        {
            goto unknow;
        }
        /* 取得第一个字节由此判断该行是否为NULL */
        i_ret = bytebuff_get_char(p_st_data, &u8_flg);
        if (i_ret != FR_SUCC)
        {
            return APM_L7_ANALYZE_FAIL;
        }

        /* 当前列数据为NULL */
        if (u8_flg == 0xFF)
        {
            continue;
        }
        /* 解析当前列 */
        else
        {
            i_ret = db2_skip_one_cloum(p_st_data, i_whole_flg
                                       ,&p_st_fragment->ui_left_ddm_len
                                       , p_lst_metadata);
            if (i_ret != APM_L7_ANALYZE_SUCC)
            {
                return i_ret;
            }
        }
        ul_rows++;
    }

    p_st_fragment->ui_left_ddm_len = 0;
    p_st_fragment->i_req_resp_cp = DRDA_CP_NULL;
    *p_ul_rows = ul_rows;
    return APM_L7_ANALYZE_SUCC;

unknow:
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        p_st_fragment->ui_left_ddm_len = ui_len_org;
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  解析数据
*  ARGS     :  p_st_data (bytebuffer数据)
*           :  i_whole_flg(packet是否完整)
*           :  ui_data_len(数据长度)
*           :  i_typdef(type define)
*           :  p_lst_metadata(DB2 metadata list)
*           :  p_lst_bind(DB2 bind list)
*           :  p_ui_ddm_left_len(剩余DDM长度)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_lst_bind必须不为NULL
*******************************************************************************/
int db2_parse_sqldata(Frbyte_Packet *p_st_data
                     , int i_whole_flg
                     , int i_typdef
                     , unsigned int ui_data_len
                     , Frlist_header *p_lst_metadata
                     , Frlist_header *p_lst_bind
                     , unsigned int *p_ui_ddm_left_len)
{
    int i_ret = FR_SUCC;
    uint8_t u8_flg = 0;
    unsigned int ui_len = ui_data_len;
    Frlist_node *p_st_node = NULL;
    Sql_field_bind *p_st_bind = NULL;

    /* 数据格式不正 */
    if (*p_ui_ddm_left_len < ui_len)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    while (ui_len)
    {
        ui_len--;
        /* 数据不足 */
        if (bytebuff_remaining(p_st_data) <= 0)
        {
            goto unknow;
        }
        /* 取得第一个字节由此判断该行是否为NULL */
        i_ret = bytebuff_get_char(p_st_data, &u8_flg);
        if (i_ret != FR_SUCC)
        {
            frlist_remove_all(p_lst_bind, frdb_field_bind_node_free);
            return APM_L7_ANALYZE_FAIL;
        }

        /* 当前列数据为NULL */
        if (u8_flg == 0xFF)
        {
            continue;
        }
        /* 解析当前列 */
        else
        {
            i_ret = db2_parse_one_cloum(p_st_data, i_whole_flg, i_typdef
                                       ,&ui_len, p_lst_metadata, &p_st_bind);
            if (i_ret != APM_L7_ANALYZE_SUCC)
            {
                frlist_remove_all(p_lst_bind, frdb_field_bind_node_free);
                return i_ret;
            }

            /* 创建并追加节点 */
            p_st_node = frlist_node_create(p_st_bind);
            if (p_st_node == NULL)
            {
                frdb_field_bind_free(&p_st_bind);
                frlist_remove_all(p_lst_bind, frdb_field_bind_node_free);
                return APM_L7_ANALYZE_FAIL;
            }
            frlist_push(p_lst_bind, p_st_node);
        }
    }

    *p_ui_ddm_left_len -= ui_data_len;
    return APM_L7_ANALYZE_SUCC;

unknow:
    frlist_remove_all(p_lst_bind, frdb_field_bind_node_free);
    if (i_whole_flg == DB2_TRUE)
    {
        return APM_L7_ANALYZE_FAIL;
    }
    else
    {
        return APM_L7_ANALYZE_TODO;
    }
}

/*******************************************************************************
*  FUNC     :  解析FDODSC取得metadata
*  ARGS     :  p_st_data(数据)
*           :  i_whole_flg(packet完整标识)
*           :  ui_fdodsc_len(FDODSC数据长度)
*           :  p_lst_metadata(metadata节点)
*           :  p_ui_ddm_left_len(DDM遗留长度)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :  p_lst_metadata不能为NULL
*******************************************************************************/
int db2_get_fdodsc(Frbyte_Packet *p_st_data
                  , int i_whole_flg
                  , unsigned int ui_fdodsc_len
                  , Frlist_header *p_lst_metadata
                  , unsigned int *p_ui_ddm_left_len)
{
    int i_ret = FR_SUCC;
    uint8_t u8_type = 0;
    uint8_t u8_length = 0;
    unsigned int ui_len = ui_fdodsc_len;

    /* 数据格式不正 */
    if (*p_ui_ddm_left_len < ui_fdodsc_len)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 长度不足 */
    if (ui_fdodsc_len > (unsigned int)bytebuff_remaining(p_st_data))
    {
        if (i_whole_flg == DB2_TRUE)
        {
            return APM_L7_ANALYZE_FAIL;
        }
        else
        {
            return APM_L7_ANALYZE_TODO;
        }
    }

    /* 清空原有数据 */
    frlist_remove_all(p_lst_metadata, frdb_metadata_node_free);
    /* 取得第一个data length */
    i_ret = bytebuff_get_char(p_st_data, &u8_length);
    if (i_ret != FR_SUCC || ui_fdodsc_len < u8_length || u8_length < 3)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* 取得第一个data type */
    i_ret = bytebuff_get_char(p_st_data, &u8_type);
    if (i_ret != FR_SUCC)
    {
        return APM_L7_ANALYZE_FAIL;
    }

    /* DB2说明是alaways 0x76 */
    if (u8_type != 0x76)
    {
        frdbg("Please attention");
        bytebuff_skip(p_st_data, ui_fdodsc_len - 2);
        *p_ui_ddm_left_len -= ui_fdodsc_len;
        return APM_L7_ANALYZE_SUCC;
    }
    /* 跳过Identity */
    bytebuff_skip(p_st_data, 1);
    ui_len -= u8_length;

    i_ret = db2_parse_sqldtagrp(p_st_data, i_whole_flg, u8_length - 3
                               , p_lst_metadata);
    if (i_ret != APM_L7_ANALYZE_SUCC)
    {
        frlist_remove_all(p_lst_metadata, frdb_metadata_node_free);
        return i_ret;
    }

    /* 查看是否还有后续的 */
    while (ui_len)
    {
        /* 取得data length */
        i_ret = bytebuff_get_char(p_st_data, &u8_length);
        if (i_ret != FR_SUCC || ui_len < u8_length || u8_length < 3)
        {
            frlist_remove_all(p_lst_metadata, frdb_metadata_node_free);
            return APM_L7_ANALYZE_FAIL;
        }

        /* 取得data type */
        i_ret = bytebuff_get_char(p_st_data, &u8_type);
        if (i_ret != FR_SUCC)
        {
            frlist_remove_all(p_lst_metadata, frdb_metadata_node_free);
            return APM_L7_ANALYZE_FAIL;
        }
        /* 跳过Identity */
        bytebuff_skip(p_st_data, 1);
        ui_len -= u8_length;

        /* data type是0x7F表示还有后续描述 */
        if (u8_type == 0x7F)
        {
            i_ret = db2_parse_sqldtagrp(p_st_data, i_whole_flg, u8_length - 3
                                       , p_lst_metadata);
            if (i_ret != APM_L7_ANALYZE_SUCC)
            {
                frlist_remove_all(p_lst_metadata, frdb_metadata_node_free);
                return i_ret;
            }
        }
        else
        {
            bytebuff_skip(p_st_data, u8_length - 3);
            break;
        }
    }

    /* 跳过解析无关数据 */
    bytebuff_skip(p_st_data, ui_len);
    *p_ui_ddm_left_len -= ui_fdodsc_len;
    return APM_L7_ANALYZE_SUCC;
}
